Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Сохранить timestamp при создании записи  [new]
нязнайка
Guest
Я хочу сохранить значение timestamp при создании записи без тригера.
Т.е у меня в таблице 2 столбца : InsertTimestamp VARBINARY(8) и LastTimestamp TIMESTAMP.
Заполнить InsertTimestamp дефолтом нельзя, тригером не хочется.

Подскажите надежный ли это способ ? :
SELECT  
           CAST(CAST(@@DBTS AS BIGINT) + CAST(1 AS BIGINT) AS VARBINARY(8))

Может какая-нибудь другая сессия получить текущий + 1 до меня ?
Тестировал вставкой в 4 потока, дублей пока что не получил.
Но не уверен, может еще как нибудь можно ?
23 окт 12, 17:57    [13364603]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
просто создайье поле с типом timestamp в таблице
23 окт 12, 18:02    [13364632]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
нязнайка
Подскажите надежный ли это способ?
Имхо, нет.
Ну и потом, зачем этот начальный TS нужен?
23 окт 12, 18:05    [13364648]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
нязнайка
Guest
автор
Ну и потом, зачем этот начальный TS нужен?

Для определения существовала ли запись на момент прошлой синхронизации, новая она или нет.
23 окт 12, 18:09    [13364677]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
нязнайка
Guest
Сделал 10 потоков и дубли появились.
23 окт 12, 18:11    [13364695]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
нязнайка
автор
Ну и потом, зачем этот начальный TS нужен?

Для определения существовала ли запись на момент прошлой синхронизации, новая она или нет.
Ну так не проще ли завести чекпоинты при синхронизации? Тогда все записи, у которых ts больше ts из последнего чекпоинта, и есть новые.
23 окт 12, 18:13    [13364715]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
нязнайка
Я хочу сохранить значение timestamp при создании записи без тригера.

ALTER TABLE [таблица]
    ADD [поле-дата] smalldatetime NULL
    CONSTRAINT DF_наименование DEFAULT CURRENT_TIMESTAMP
23 окт 12, 18:17    [13364734]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
trew
нязнайка
Я хочу сохранить значение timestamp при создании записи без тригера.

ALTER TABLE [таблица]
    ADD [поле-дата] smalldatetime NULL
    CONSTRAINT DF_наименование DEFAULT CURRENT_TIMESTAMP
timestamp и время - вещи абсолютно разные.
23 окт 12, 18:18    [13364739]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
нязнайка
Guest
Ну так не проще ли завести чекпоинты при синхронизации? Тогда все записи, у которых ts больше ts из последнего чекпоинта, и есть новые.

Что за чекпоинты ?
Дело в том, что у меня немонотонно возрастающий ключ (вернее не совсем монотонно). Поэтому и использую таймстампы.

А по большому счету уникальность то и не обязательна.
Текущий @@DBTS уже был и это главное.

Спасибо за советы.
23 окт 12, 18:19    [13364745]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
нязнайка
Ну так не проще ли завести чекпоинты при синхронизации? Тогда все записи, у которых ts больше ts из последнего чекпоинта, и есть новые.

Что за чекпоинты ?
Дело в том, что у меня немонотонно возрастающий ключ (вернее не совсем монотонно). Поэтому и использую таймстампы.

А по большому счету уникальность то и не обязательна.
Текущий @@DBTS уже был и это главное.

Спасибо за советы.
Что у вас за задача? Синхронизация какая-то? Хотите отыскать новые или изменившиеся записи? Ну так запоминайте последний обработанный при синхронизации ts, и все.
23 окт 12, 18:20    [13364756]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
Гавриленко Сергей Алексеевич,

Тогда так
ALTER TABLE [таблица] ADD [поле] timestamp 

13364632
23 окт 12, 18:25    [13364789]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
нязнайка
Guest
Что у вас за задача? Синхронизация какая-то? Хотите отыскать новые или изменившиеся записи? Ну так запоминайте последний обработанный при синхронизации ts, и все.


Так если InsertTimestamp > timestamp последней синхронизации - значит запись новая и ее можно заливать балком.
А так как bulk updat-ов не придумали, то приходится заливать в staging таблицу обновленные, а потом обновлять основную таблицу.

Т.е задача - разделить обновление и вставку.
23 окт 12, 18:26    [13364790]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
нязнайка
Guest
ALTER TABLE [таблица] ADD [поле] timestamp


У меня есть уже timestamp. Я хотел его знаяение на момент вставки.
23 окт 12, 18:27    [13364798]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Crimean
Member

Откуда:
Сообщений: 13148
[quot нязнайка]
ALTER TABLE [таблица] ADD [поле] timestamp


-- drop table a
-- create table a ( id int primary key , stamp timestamp )

declare @a table ( id int primary key , stamp binary(8))

insert into a ( id ) 
output inserted.id, inserted.stamp into @a ( id, stamp )
select isnull( ( select max( id ) from a ), 0 ) + 1

select @@dbts
select top 1 * from a order by id desc
select * from @a


и "для синхронизации" - обязательно почитайте про min_active_rowversion
23 окт 12, 18:52    [13364886]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
нязнайка
Guest
[quot Crimean]
нязнайка
пропущено...


-- drop table a
-- create table a ( id int primary key , stamp timestamp )

declare @a table ( id int primary key , stamp binary(8))

insert into a ( id ) 
output inserted.id, inserted.stamp into @a ( id, stamp )
select isnull( ( select max( id ) from a ), 0 ) + 1

select @@dbts
select top 1 * from a order by id desc
select * from @a


и "для синхронизации" - обязательно почитайте про min_active_rowversion


А в чем подвох ? все 3 селекта один и тот же стэмп возвращают, как и ожидалось.

За min_active_rowversion спасибо. Я в курсе отличия от @@DBTS.
Ведь если не использовать версионники (RCSI), то никакие изменения не потеряется. Будет блокировка висеть, читатель будет ждать, пока транзакция закончится и все. Простое ожидание.
Или я что-то не понимаю ?
24 окт 12, 16:59    [13370041]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Crimean
Member

Откуда:
Сообщений: 13148
нязнайка
А в чем подвох


нет подвоха. это наиболее дешевый и при этом корректный способ получить стэмп добавленной записи
а в некоторых случаях и единственный
насчет потерь записей - в блогах про указанную функцию все достаточно расписано :) местами даже с картинками
минус - пока будут висеть "длинные" транзакции - вы не будете выгребать изменений, но это нормально и лучше пропуска изменений
24 окт 12, 20:36    [13371078]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
нязнайка
Guest
Так ожидания будут в любом случае даже с min_active без версионника. (Получили мин, стали читать данные, пока читаем кто-нибудь старинную запись поменял, результат- ждем конца транзакции).

Но как данные могут потеряться не представляю и найти не могу.

Нашел вот статью :

Will you use @@DBTS to determine current unprocessed row version or use Max_Active_RowVersion? Answer is the row versions less than Max_Active_RowVersion. The reason is that using Max_Active_Rowversion can guarantee the rows processed by ETL are already committed. If ETL uses @@DBTS to determine current row version, there is a chance that any active transaction holds the records until ETL process complete so that ETL could not see those records and would not process them. But when next ETL cycle comes, it ignores those rows since the row version of those rows are processed.


из @@DBTS vs MIN_ACTIVE_ROWVERSION

Неужели могут быть потери в обычном READ COMMITTED ?
24 окт 12, 20:50    [13371119]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Crimean
Member

Откуда:
Сообщений: 13148
нязнайка,

могут быть и природа не в версионнике )
24 окт 12, 22:54    [13371554]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
нязнайка
Guest
Вот к примеру есть таблица :

CREATE TABLE dbo.a (id INT NOT NULL IDENTITY(1,1), val INT NOT NULL, stamp TIMESTAMP NOT NULL)
GO 
CREATE UNIQUE NONCLUSTERED INDEX IX_a ON dbo.a(stamp); 



CREATE PROCEDURE dbo.GetChangedRecords  
@LastTimestamp VARBINARY(8), 
@CurrentTimestamp VARBINARY(8)
AS 
SET NOCOUNT ON; 

SET TRANSACTION ISOLATION LEVEL READ COMMITTED ; 

SELECT a.id,
           a.val 
FROM dbo.a AS a 
WHERE a.stamp > @LastTimestamp AND a.stamp <= @CurrentTimestamp ;  


Где @LastTimestamp предыдущий сохраненный, а @CurrentTimestamp получен с помощью @@DBTS.

Как в этом случае можно что-то потерять при RC ?
Я понимаю было бы еще просто условие a.stamp > @LastTimestamp без верхнего ограничения.
А так с индексом по стэмпу или без ничего теряться не должно.
Можно ссылку и репро ?
25 окт 12, 11:13    [13372916]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Crimean
Member

Откуда:
Сообщений: 13148
нязнайка,

вы же сами нашли эти статьи, где показывалось как теряются данные с @@dbts, почему и зачем ввели "ту самую" функцию
25 окт 12, 12:10    [13373371]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
нязнайка
Guest
there is a chance that any active transaction holds the records until ETL process complete so that ETL could not see those records and would not process them
.

Ну не знаю, по мне так это просто необоснованные слова. Вот это интересно : ( ETL process complete)
Как так он может закончится если строчки залочены?
По идее без грязных чтений или версионности никак.
25 окт 12, 12:36    [13373629]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Crimean
Member

Откуда:
Сообщений: 13148
нязнайка,

тогда читаем дальше и внимательнее. подсказка - @@dbts наращиватеся на каждое "намерение" и является свойством базы. "намерение" не означает завершение транзакции. полная аналогия с identity в некотором смысле. в результате, определенная комбинация завершенных и незавершенных транзакций приводит к тому, что работа по @@dbts приводит к "дыркам" в данных. это где-то в блогах с картинками было показано. брать надо не до @@dbts а именно до значения указанной функции, тогда дырок не будет гарантировано. а снапшоты позволят вам не прибегать к верхним уровням изоляции, что было бы неизбежно (!) - при работе в обычном "read committed" вы "легко" получаете как минимум дубли вплоть до дублей ПК. репро было, раскладное, ооочень лениво искать. даже проблему в MS файлил в свое время. так что рекомендую сэкономить свое время и перейти на использование "той самой" функции, благо ее именно для этого и сделали
25 окт 12, 12:57    [13373757]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Виктор_sql
Member

Откуда:
Сообщений: 97
Может вариант,
одно timestamp поле сделать null, будет для одной операции
а второе вовсе нет (not null)
м ?
18 дек 12, 16:24    [13649665]     Ответить | Цитировать Сообщить модератору
 Re: Сохранить timestamp при создании записи  [new]
Виктор_sql
Member

Откуда:
Сообщений: 97
а хелп говорит, такое поле может быть только одно. сам себе и ответил)
18 дек 12, 16:34    [13649739]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить