powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Оповещение клиентов о добавлении записи в таблицу
12 сообщений из 12, страница 1 из 1
Оповещение клиентов о добавлении записи в таблицу
    #40040941
kikipumpa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Тема не раз поднималась, но конкретного ответа так и не нашёл.
Изначально был Firebird. Там всё решалось просто: в триггере на Insert отправляем событие:
Код: plsql
1.
post_event 'new_event'

а на клиенте была подписка на событие:
Код: c#
1.
2.
fbRemoteEvent.AddEvents("new_event");
fbRemoteEvent.RemoteEventCounts += FbRemoteEvent_RemoteEventCounts;


и в обработчике делай что хочешь с этим.
Сейчас нужно перенести всё на MS SQL. Собственно вопрос - как организовать подобное?
Читал про Service Broker, но не догоняю, как его можно применить в такой ситуации, слишком он громоздкий, а примеров использования подробных не нашел.
...
Рейтинг: 0 / 0
Оповещение клиентов о добавлении записи в таблицу
    #40040945
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чо все на эту deperecated технологию сервис-брокера зациклились?

sp_getapplock + асинхронное исполнение запроса на клиенте.
...
Рейтинг: 0 / 0
Оповещение клиентов о добавлении записи в таблицу
    #40040958
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222,

где это ты прочитал что она deprecated?


kikipumpa
читайте про SqlDependency / SqlNotificationRequest
...
Рейтинг: 0 / 0
Оповещение клиентов о добавлении записи в таблицу
    #40041071
kikipumpa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
felix_ff,

Спасибо, SqlDependency похоже на то, что мне надо.
Я правильно понимаю, что если у меня несколько таблиц, то мне надо на каждую делать экземпляр SqlDependency и EventHandler?
И SqlDependency работает ведь с сервис-брокером, его нужно настраивать? С одной таблицей вроде бы заработало без настроек, а вот с несколькими пока нет.
...
Рейтинг: 0 / 0
Оповещение клиентов о добавлении записи в таблицу
    #40041191
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kikipumpa
С одной таблицей вроде бы заработало без настроек

Не забудь проверить, что ты не получаешь уведомлений об изменениях, сделанных в транзакции, закончившейся откатом.
...
Рейтинг: 0 / 0
Оповещение клиентов о добавлении записи в таблицу
    #40041225
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kikipumpa
felix_ff,

Спасибо, SqlDependency похоже на то, что мне надо.
Я правильно понимаю, что если у меня несколько таблиц, то мне надо на каждую делать экземпляр SqlDependency и EventHandler?
И SqlDependency работает ведь с сервис-брокером, его нужно настраивать? С одной таблицей вроде бы заработало без настроек, а вот с несколькими пока нет.


да SqlDependency это надстройка над SqlNotificationRequest которая собственно работает через ServiceBroker.
Все что нужно это включить брокер на базе данных которую собираетесь отслеживать:
Код: sql
1.
2.
alter database [base] set enable_broker;
--profit;



у SqlDependency есть ограничения и довольно много. отслеживаются в основном "тривиальные запросы"
https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms181122(v=sql.105)?redirectedfrom=MSDN

Единственный неудобный момент что зарегистрированный SqlDependency реагирует единожды на событие, и после этого его нужно заново регистрировать. из-за этого код обработчика получается несколько громоздким.

точнее есть еще неприятная хрень - это настройки SET. в каких нибудь legacy-говно базах иногда не получается использовать ее.


Не забудь проверить, что ты не получаешь уведомлений об изменениях, сделанных в транзакции, закончившейся откатом.


ноуп. эта штука уведомляет даже при откате транзакции. смысл в том что зарегистрированный SqlNotificationRequest на таблице используется оптимизатором запросов, и все DML инструкции видоизменяют план запроса. фиксация подписки проиходит всегда, вне зависимости контекста транзакции, так что сообщение ложится в очередь в любом случае.
https://docs.microsoft.com/ru-ru/sql/relational-databases/native-client/features/working-with-query-notifications?view=sql-server-ver15
...
Рейтинг: 0 / 0
Оповещение клиентов о добавлении записи в таблицу
    #40041298
kikipumpa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
felix_ff,

Не забудь проверить, что ты не получаешь уведомлений об изменениях, сделанных в транзакции, закончившейся откатом.

ноуп. эта штука уведомляет даже при откате транзакции. смысл в том что зарегистрированный SqlNotificationRequest на таблице используется оптимизатором запросов, и все DML инструкции видоизменяют план запроса. фиксация подписки проиходит всегда, вне зависимости контекста транзакции, так что сообщение ложится в очередь в любом случае.
https://docs.microsoft.com/ru-ru/sql/relational-databases/native-client/features/working-with-query-notifications?view=sql-server-ver15
То есть на клиенте я не смогу узнать, чем закончилась транзакция?
...
Рейтинг: 0 / 0
Оповещение клиентов о добавлении записи в таблицу
    #40041318
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kikipumpa,

ну всмысле не можете узнать?

к примеру лежат у вас в табличке данные:
Код: sql
1.
2.
3.
create table tbl (id int index ix clustered, type int, index ix0 (type));

insert into tbl values (1, 1), (2, 1), (3, 1), (4, 2), (5, 2);



вы хотите знать когда изменяются строки с типом type = 2
делаете подписку на команду:
Код: sql
1.
select [id] from [dbo].[tbl] where [type] = 2;



далее какая то сессия выполняет:
Код: sql
1.
2.
3.
4.
5.
6.
7.
insert into [dbo].[tbl] ([id], [type]) values (10, 3); --уведомление не приходит
go
insert into [dbo].[tbl] ([id], [type]) values (11, 2); --уведомление приходит
go
begin tran;
insert into [dbo].[tbl] ([id], [type]) values (12, 2); --уведомление приходит
rollback;



но при каждом поступлении уведомления вы же заранее знаете на что подписывались. сработало событие OnChange вы на клиенте можете взять и заселектить набор данных, а как вы уже данные обрабатываете это непосредственно логика клиента

можно сделать так что первым фетчем перед подпиской вы получаете набор данных и сохраняете к примеру в DataTable, инстанцируете SqlDependency как только срабатывает OnChange, вы селектите набор данных и сравниваете две DataTable если различия есть значит Commit был.

причем у делегата OnChangeEventHandler аргумент SqlNotificationEventArgs тоже имеет много свойств описывающих событие. ( но вроде на откат там никаких флагов на моей памяти нет)
...
Рейтинг: 0 / 0
Оповещение клиентов о добавлении записи в таблицу
    #40041524
kikipumpa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
felix_ff,

felix_ffвы селектите набор данных и сравниваете две DataTable если различия есть значит Commit был.
ну это то понятно, я имел в виду из уведомления узнать.

В общем, спасибо, разобрался. Всё оказалось проще, чем казалось.
...
Рейтинг: 0 / 0
Оповещение клиентов о добавлении записи в таблицу
    #40041599
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
сработало событие OnChange вы на клиенте можете взять и заселектить набор данных

А если оно сработало ещё до коммита пишущей транзакции - придётся использовать уровень изоляции dirty read?..
...
Рейтинг: 0 / 0
Оповещение клиентов о добавлении записи в таблицу
    #40041603
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
felix_ff
сработало событие OnChange вы на клиенте можете взять и заселектить набор данных

А если оно сработало ещё до коммита пишущей транзакции - придётся использовать уровень изоляции dirty read?..


хм :) хороший вопрос.

да, но тогда мы прочитаем незакоммиченные данные и нифига не поймем будет ли последующий коммит или нет.
я бы в таком случае ввел некую условность в виде: по уведомлению читаем набор с read committed и выставляем commandTimeout равным некоему предопределенному времени которое мы считаем приемлемым для завершения почти любой операции с таблицей. (подбирается эмперически)

вычитка блокируется на момент работы транзакции, если транзакция за наше "приемлемое время" завершится коммитом или роллбеком мы узнаем результат, если получим SqlException по таймауту, то будем считать что транзакция длинная ну и предпринимаем или еще попытки вычитки или применяем какую то другую логику обработки

согласен что с явными долгими транзакциями данная технология уведомлений возможно не идеальный вариант, она обычно хорошо работает когда в базе по большей части все dml используются под обычным autocommit, без явных транзакций
...
Рейтинг: 0 / 0
Оповещение клиентов о добавлении записи в таблицу
    #40041731
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какой смысл информировать о незафиксированных данных? Кот ни жив, ни мёртв.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Оповещение клиентов о добавлении записи в таблицу
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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