powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Узнать какая из параллельных транзакций была последней без использования rowversion
20 сообщений из 20, страница 1 из 1
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918612
peon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Предположим, строку таблицы многопоточно изменяет множество хранимых процедур.

Каждая процедура имеет возможность узнать конечный результат своих действий над данными(свою последнюю версию данных) и вернуть его вызывающей стороне(коллеру) образуя коллекцию.

Вопрос: как мне узнать, какое из возвр. значений будет новейшим(последним) в коллекции?

Если добавить rowversion то соотв. включится счетчик обновлений, который можно вернуть с возвращаемым значением и тем самым определить последнее изменение данных, но хотелось бы решение без создания доп колонки.

Я было подумал, что @@DBTS инкрементится при каждом обновлении базы, но нет - только при добавлении rowversion в соотв таблицу.

Может есть какой еще счетчик? Я так понимаю, что всякие transaction_id transaction_sequence_num мне тут не помогут..

Спасиб...
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918621
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
peon
Каждая процедура имеет возможность узнать конечный результат своих действий над данными(свою последнюю версию данных) и вернуть его вызывающей стороне(коллеру) образуя коллекцию.

Вопрос: как мне узнать, какое из возвр. значений будет новейшим(последним) в коллекции?
Если "Каждая процедура имеет возможность узнать конечный результат своих действий", то этот результат и является последним.

Узнать это можно, используя "output" в командах изменений.
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918625
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
peon
Может есть какой еще счетчик?
Код: sql
1.
2.
3.
4.
5.
select
 dt.database_transaction_last_lsn
from
 sys.dm_tran_current_transaction ct join
 sys.dm_tran_database_transactions dt on dt.transaction_id = ct.transaction_id and dt.database_id = db_id();
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918654
peon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alexeyvg
peon
Каждая процедура имеет возможность узнать конечный результат своих действий над данными(свою последнюю версию данных) и вернуть его вызывающей стороне(коллеру) образуя коллекцию.

Вопрос: как мне узнать, какое из возвр. значений будет новейшим(последним) в коллекции?
Если "Каждая процедура имеет возможность узнать конечный результат своих действий", то этот результат и является последним.

Узнать это можно, используя "output" в командах изменений.


В контексте самой процедуры естественно ее результат будет последним, но в в контексте пула одновременно выполняемых процедур нет. Мне это все нужно, чтобы возвращаемые данные одновременно застряли в моем кэше, ну и версия(через перезаписывания) этих данных была бы последней(относительно несуществующего rowversion). Если бы база инкрементила @@DBTS при каждом обновлении любой строки я бы мог просто использовать этот счетчик для упорядочивания версий данных.
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918660
peon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm
peon
Может есть какой еще счетчик?
Код: sql
1.
2.
3.
4.
5.
select
 dt.database_transaction_last_lsn
from
 sys.dm_tran_current_transaction ct join
 sys.dm_tran_database_transactions dt on dt.transaction_id = ct.transaction_id and dt.database_id = db_id();



Ой как все сложно. :) Я так и подумал, что единственный вариант - это через место транзакции в логе..
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918661
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
@@DBTS возвращает последний сгенерированный rowversion для базы, а не для конкретной сессии. И между модификацией данных в вашей сессии и получением значения переменной, запросто может произойти еще одна модификация, и в вашей сессии вы получите уж не свой, а чужой rowversion.

На lsn я бы тоже не стал закладываться. Плохо использовать физические инструменты, которые от версии к версии могут меняться, для решения логической задачи.
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918663
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
peon,

причем здесь пул? Значит он у Вас неверно организован. Выполнение процедур атомарно в рамках транзакции. Т.е. каждая процедура совершенно точно "знает", что она сделала и может вернуть результат пулу. Извлечь данные, которые обработала процедура, можно введение кода в процедуру с выражением запроса output, как писали об этом.
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918680
peon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гавриленко Сергей Алексеевич
На lsn я бы тоже не стал закладываться. Плохо использовать физические инструменты, которые от версии к версии могут меняться, для решения логической задачи.


А что делать - иначе задачу не решить.
Кстати на lsn(логе) работают многие продвинутые инструменты( https://debezium.io/ )

...

У меня могут быть сотни одновременных писателей в счетчик и как мне уведомлять "старых" клиентов о том, что их данные со счетчика устарели - не заставлять же их поллить базу - только через пуш в них новой версии - а это уже кеширование(версионность) на уровне приложения, но в кеше то должна всегда находится последнее обновление счетчика, соотв. запись в кэш происходит через условие, такое как rowversion или вот тот же LSN - надеюсь он доступен из контекста хранимой процедуры или сразу после нее, уникально характеризуя оставленный в базе след и его версию.
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918682
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
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918684
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
peon,

авторкак мне уведомлять "старых" клиентов о том, что их данные со счетчика устарели
это же другая задача, не та, что описана в начале.
Задача информирования клиентского приложения об изменениях в базе можно реализовать, например, как в статье https://github.com/dyatchenko/ServiceBrokerListener .
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918696
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
То он бы сразу стал не нужен в ситуации, когда за раз меняется более одной строки.
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918701
peon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гавриленко Сергей Алексеевич,

логично, надо же сериализовать в рамках потока изменений даже в контексте одной транзакции, т.е. буквально каждое обновление строки соотносить с уникальным значением счетчика.. ох, тогда и lsn отлетает, т.к. он характеризует совокупность изменений за одну транзакцию
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918703
peon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов,

мне кажется https://github.com/dyatchenko/ServiceBrokerListener в итоге будет гораздо медленнее решения на rowversion
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918711
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
use tempdb;
go

create table dbo.t (id int primary key, v int);
insert into dbo.t values (1, 1);
go

begin tran;

update dbo.t set v += 1 where id = 1;

select
 dt.database_transaction_last_lsn
from
 sys.dm_tran_current_transaction ct join
 sys.dm_tran_database_transactions dt on dt.transaction_id = ct.transaction_id and dt.database_id = db_id();

update dbo.t set v += 1 where id = 1;

select
 dt.database_transaction_last_lsn
from
 sys.dm_tran_current_transaction ct join
 sys.dm_tran_database_transactions dt on dt.transaction_id = ct.transaction_id and dt.database_id = db_id();
rollback;
go

drop table dbo.t;
go
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918736
Gerros
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
peon
У меня могут быть сотни одновременных писателей в счетчик и как мне уведомлять "старых" клиентов о том, что их данные со счетчика устарели
А зачем этим писателям знать что счётчик устарел?

Вы собираетесь сделать кэш, который будет отправлять уведомления клиентам об изменении счётчика.
А почему бы не сделать так, чтобы клиент получать значение счётчика не запуском хранимки, а через этот ваш кэш? А уже кэш будет выстраивать клиентские запросы в очередь, работать с базой и уведомлять клиентов.

А вообще, можете сформулировать задачу как она есть, а не как вы собрались её решать?
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39918797
peon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gerros,

Так кэш же сам должен быть в актуальном состоянии(содержать последние изменения счетчиков).

...

В общем идея сделать все по другому, через динамические таблицы.

При первом изменении счетчика регистрировать клиента(терминал) через создание соотв. таблицы при дальнейших изменениях счетчика со стороны первого клиента и последующих дополнять таблицу идентификаторами новых клиентов(подписчиков на изменение данных). Ну и по таймеру периодически бегать по такой таблице и обновлять счетчики у клиентов через пуш(если клиент отвалился и не отреагировал на пуш сотв. удалять его ID из таблицы подписчиков на соотв счетчик).

Т.е. обновление устаревших версий данных счетчиков на терминалах клиентов делать асинхронным.
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39919041
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
peon,

Пробейте свои возвращаемые значение ROW_NUMBER, если там нет IDENTITY и успокойтесь. И что в вашем понимании последнее? Последняя запись по номеру, последняя по некоей дате? Вы кинули в таблицу 10 записей, если у них нет сортирующего ключа, то понятия "первое" "предыдущее" "последнее" тут отсутствует.
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39919046
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
peon,

Для лиц понимающих толк в извращениях

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
use tempdb
go
CREATE TABLE T(X INT);

INSERT INTO T VALUES(1),(2)

SELECT %%physloc%% AS [%%physloc%%],
       sys.fn_PhysLocFormatter(%%physloc%%) AS [File:Page:Slot]
FROM T
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39919057
Фотография Exproment
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
peon
Предположим, строку таблицы многопоточно изменяет множество хранимых процедур.

Каждая процедура имеет возможность узнать конечный результат своих действий над данными(свою последнюю версию данных) и вернуть его вызывающей стороне(коллеру) образуя коллекцию.

Вопрос: как мне узнать, какое из возвр. значений будет новейшим(последним) в коллекции?

Версионность в разрезе каждой строки ? Вам не нужен rowversion. Добавлете поле inc_version и делаете его +1 каждый апдейтом, через output получаете результат и возвращаете клиенту.

Если нужно глобально, то:
  • можете сразу после апдейта делать +1 через сиквенс, возвращая результат клиенту. Но надо протестить под нагрузкой, может не прокатит.
  • создаете таблицу логов с монотонно возрастающим ключен, который получаете из неё - 100% рабочий вариант.
...
Рейтинг: 0 / 0
Узнать какая из параллельных транзакций была последней без использования rowversion
    #39919070
Фотография Exproment
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Exproment
можете сразу после апдейта делать +1 через сиквенс, возвращая результат клиенту. Но надо протестить под нагрузкой, может не прокатит.

В общем тут надо просто транзакцию закрывать после next value for, чтобы гарантировать что никто не вклинится между апдейтом записи и операцией +1. Вот так у вас будут версии, без изменения структуры таблиц:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
begin tran

	update my_table
	set		my_data = 'the most ne data'
	where	my_key = 1 

	select next value for dbo.seq_version

commit
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Узнать какая из параллельных транзакций была последней без использования rowversion
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]