|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
Предположим, строку таблицы многопоточно изменяет множество хранимых процедур. Каждая процедура имеет возможность узнать конечный результат своих действий над данными(свою последнюю версию данных) и вернуть его вызывающей стороне(коллеру) образуя коллекцию. Вопрос: как мне узнать, какое из возвр. значений будет новейшим(последним) в коллекции? Если добавить rowversion то соотв. включится счетчик обновлений, который можно вернуть с возвращаемым значением и тем самым определить последнее изменение данных, но хотелось бы решение без создания доп колонки. Я было подумал, что @@DBTS инкрементится при каждом обновлении базы, но нет - только при добавлении rowversion в соотв таблицу. Может есть какой еще счетчик? Я так понимаю, что всякие transaction_id transaction_sequence_num мне тут не помогут.. Спасиб... ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 04:20 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
peon Каждая процедура имеет возможность узнать конечный результат своих действий над данными(свою последнюю версию данных) и вернуть его вызывающей стороне(коллеру) образуя коллекцию. Вопрос: как мне узнать, какое из возвр. значений будет новейшим(последним) в коллекции? Узнать это можно, используя "output" в командах изменений. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 09:19 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
peon Может есть какой еще счетчик? Код: sql 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 10:19 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
alexeyvg peon Каждая процедура имеет возможность узнать конечный результат своих действий над данными(свою последнюю версию данных) и вернуть его вызывающей стороне(коллеру) образуя коллекцию. Вопрос: как мне узнать, какое из возвр. значений будет новейшим(последним) в коллекции? Узнать это можно, используя "output" в командах изменений. В контексте самой процедуры естественно ее результат будет последним, но в в контексте пула одновременно выполняемых процедур нет. Мне это все нужно, чтобы возвращаемые данные одновременно застряли в моем кэше, ну и версия(через перезаписывания) этих данных была бы последней(относительно несуществующего rowversion). Если бы база инкрементила @@DBTS при каждом обновлении любой строки я бы мог просто использовать этот счетчик для упорядочивания версий данных. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 13:48 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
invm peon Может есть какой еще счетчик? Код: sql 1. 2. 3. 4. 5.
Ой как все сложно. :) Я так и подумал, что единственный вариант - это через место транзакции в логе.. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 13:52 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
@@DBTS возвращает последний сгенерированный rowversion для базы, а не для конкретной сессии. И между модификацией данных в вашей сессии и получением значения переменной, запросто может произойти еще одна модификация, и в вашей сессии вы получите уж не свой, а чужой rowversion. На lsn я бы тоже не стал закладываться. Плохо использовать физические инструменты, которые от версии к версии могут меняться, для решения логической задачи. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 13:57 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
peon, причем здесь пул? Значит он у Вас неверно организован. Выполнение процедур атомарно в рамках транзакции. Т.е. каждая процедура совершенно точно "знает", что она сделала и может вернуть результат пулу. Извлечь данные, которые обработала процедура, можно введение кода в процедуру с выражением запроса output, как писали об этом. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 14:04 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
Гавриленко Сергей Алексеевич На lsn я бы тоже не стал закладываться. Плохо использовать физические инструменты, которые от версии к версии могут меняться, для решения логической задачи. А что делать - иначе задачу не решить. Кстати на lsn(логе) работают многие продвинутые инструменты( https://debezium.io/ ) ... У меня могут быть сотни одновременных писателей в счетчик и как мне уведомлять "старых" клиентов о том, что их данные со счетчика устарели - не заставлять же их поллить базу - только через пуш в них новой версии - а это уже кеширование(версионность) на уровне приложения, но в кеше то должна всегда находится последнее обновление счетчика, соотв. запись в кэш происходит через условие, такое как rowversion или вот тот же LSN - надеюсь он доступен из контекста хранимой процедуры или сразу после нее, уникально характеризуя оставленный в базе след и его версию. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 14:45 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
Гавриленко Сергей Алексеевич @@DBTS возвращает последний сгенерированный rowversion для базы, а не для конкретной сессии. Да, вот если бы каждый поток сохранял @@DBTS в собственный счетчик(эдакий rowversion, но в рамках всей базы а не отдельной строки и в рамках каждого потока)... ну и инкрементится @@DBTS только для строк с rowversion https://docs.microsoft.com/en-us/sql/t-sql/data-types/rowversion-transact-sql?view=sql-server-ver15 ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 14:50 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
peon, авторкак мне уведомлять "старых" клиентов о том, что их данные со счетчика устарели это же другая задача, не та, что описана в начале. Задача информирования клиентского приложения об изменениях в базе можно реализовать, например, как в статье https://github.com/dyatchenko/ServiceBrokerListener . ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 14:58 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
peon Гавриленко Сергей Алексеевич @@DBTS возвращает последний сгенерированный rowversion для базы, а не для конкретной сессии. Да, вот если бы каждый поток сохранял @@DBTS в собственный счетчик(эдакий rowversion, но в рамках всей базы а не отдельной строки и в рамках каждого потока)... ну и инкрементится @@DBTS только для строк с rowversion https://docs.microsoft.com/en-us/sql/t-sql/data-types/rowversion-transact-sql?view=sql-server-ver15 ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 15:55 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
Гавриленко Сергей Алексеевич, логично, надо же сериализовать в рамках потока изменений даже в контексте одной транзакции, т.е. буквально каждое обновление строки соотносить с уникальным значением счетчика.. ох, тогда и lsn отлетает, т.к. он характеризует совокупность изменений за одну транзакцию ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 16:44 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
Владислав Колосов, мне кажется https://github.com/dyatchenko/ServiceBrokerListener в итоге будет гораздо медленнее решения на rowversion ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 16:48 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
peon тогда и lsn отлетает, т.к. он характеризует совокупность изменений за одну транзакцию Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 17:55 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
peon У меня могут быть сотни одновременных писателей в счетчик и как мне уведомлять "старых" клиентов о том, что их данные со счетчика устарели Вы собираетесь сделать кэш, который будет отправлять уведомления клиентам об изменении счётчика. А почему бы не сделать так, чтобы клиент получать значение счётчика не запуском хранимки, а через этот ваш кэш? А уже кэш будет выстраивать клиентские запросы в очередь, работать с базой и уведомлять клиентов. А вообще, можете сформулировать задачу как она есть, а не как вы собрались её решать? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2020, 23:39 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
Gerros, Так кэш же сам должен быть в актуальном состоянии(содержать последние изменения счетчиков). ... В общем идея сделать все по другому, через динамические таблицы. При первом изменении счетчика регистрировать клиента(терминал) через создание соотв. таблицы при дальнейших изменениях счетчика со стороны первого клиента и последующих дополнять таблицу идентификаторами новых клиентов(подписчиков на изменение данных). Ну и по таймеру периодически бегать по такой таблице и обновлять счетчики у клиентов через пуш(если клиент отвалился и не отреагировал на пуш сотв. удалять его ID из таблицы подписчиков на соотв счетчик). Т.е. обновление устаревших версий данных счетчиков на терминалах клиентов делать асинхронным. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.01.2020, 13:40 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
peon, Пробейте свои возвращаемые значение ROW_NUMBER, если там нет IDENTITY и успокойтесь. И что в вашем понимании последнее? Последняя запись по номеру, последняя по некоей дате? Вы кинули в таблицу 10 записей, если у них нет сортирующего ключа, то понятия "первое" "предыдущее" "последнее" тут отсутствует. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2020, 12:44 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
peon, Для лиц понимающих толк в извращениях Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2020, 12:48 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
peon Предположим, строку таблицы многопоточно изменяет множество хранимых процедур. Каждая процедура имеет возможность узнать конечный результат своих действий над данными(свою последнюю версию данных) и вернуть его вызывающей стороне(коллеру) образуя коллекцию. Вопрос: как мне узнать, какое из возвр. значений будет новейшим(последним) в коллекции? Версионность в разрезе каждой строки ? Вам не нужен rowversion. Добавлете поле inc_version и делаете его +1 каждый апдейтом, через output получаете результат и возвращаете клиенту. Если нужно глобально, то:
... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2020, 13:12 |
|
Узнать какая из параллельных транзакций была последней без использования rowversion
|
|||
---|---|---|---|
#18+
Exproment можете сразу после апдейта делать +1 через сиквенс, возвращая результат клиенту. Но надо протестить под нагрузкой, может не прокатит. В общем тут надо просто транзакцию закрывать после next value for, чтобы гарантировать что никто не вклинится между апдейтом записи и операцией +1. Вот так у вас будут версии, без изменения структуры таблиц: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.01.2020, 13:38 |
|
|
start [/forum/topic.php?fid=46&tid=1686597]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
36ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 141ms |
0 / 0 |