Опрос на изменения базы данных: SqlDependency, SignalR это хорошо

Было бы хорошо, если мне нужно показать данные об изменениях в БД через SQL-зависимость и сигнализатор. предположим, моя таблица транзакций часто менялась многими людьми. Предположим, что за несколько секунд данные меняются много раз, тогда я хотел бы знать, как уведомление перейдет в класс зависимостей sql?

данные изменения будут поставлены в очередь перед sql классом зависимостей? Класс зависимостей sql может обрабатывать изменения данных, когда изменения будут вносить огромные объемы трафика?

здесь я читал статью о SqlDependency & SignalR. ссылка http://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency

Несколько вещей было не ясно для меня.

  1. как дать разрешение на уведомление о запросе на подписку в IIS?
  2. пожалуйста, смотрите строку в этой статье.

,

private void dependency_OnChange(object sender, SqlNotificationEventArgs e) {
    JobHub.Show();
}

когда данные изменятся, будет запущено событие dependency_OnChange и JobHub.Show(); звонит

JobHub is name of class and not static class so i like to know how anyone can call `JobHub.Show();` from out side ??
  1. Что такое класс GlobalHost и когда он используется?
  2. проблема, связанная с кодом статьи. просто перейдите по этой ссылке

http://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency

посмотрите на код jquery, который выбирает данные и заполняет таблицу. в первый раз, когда загрузка страницы предполагает, что в таблице существует 5 записей, поэтому 5 записей будут переданы в код jquery, и он будет просто отображать эти 5 записей, но когда любые существующие данные будут изменены в таблице, что произойдет??

единственные измененные строки поступят на клиентскую сторону или все данные, включая измененные данные, попадут на клиентскую сторону?

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

пожалуйста, ради бога, прочитайте ссылку на статью один раз, а затем ответьте на мой вопрос. Спасибо

пожалуйста, направь меня. Спасибо

2 ответа

Хорошо, ManniAT близок, но не совсем на высоте, здесь происходит то, что события уведомления SQLDependency - это одноразовая сделка. Так что, как он указывает, он сработает с первого раза. Вам нужно удалить этот обработчик (это предотвращает сценарий с несколькими выстрелами при последующем вызове метода) и повторно добавить его, чтобы он снова сработал. Если вы не хотите возвращать свои данные напрямую из метода установки SQLDependency, (и я рекомендую этого не делать), вы можете вызывать этот метод, когда вам когда-нибудь понадобится восстановить слушателя.

Ответы: 1) После срабатывания уведомления вы вызываете метод на концентраторе, который обновляет данные, которые изменились. Уведомления SqlDependency должны быть как можно более конкретными, и при их запуске вы должны уже знать, какую часть пользовательского интерфейса необходимо обновить.

2) Вы не установили свой Hub в качестве статического класса, и, следовательно, вы не можете вызывать методы класса, не создав сначала экземпляр класса, прежде чем вызывать метод show. В этом примере я считаю, что это статический класс, поэтому оно работает. Создание хаба в качестве статического класса - это не то, что я бы порекомендовал в этом случае, я бы создал отдельный класс отслеживания хабов, как в этом примере. http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-server-broadcast-with-signalr-20

3) Файл GlobalHost в этом случае, я полагаю, является вашим Global.asax, где вы запускаете и останавливаете свои SqlDependencies.

Модификация к примеру:

try
        {
            using (
                var connection =
                    new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
            {
                connection.Open();
                using (SqlCommand command = new SqlCommand(@"SELECT [Id]
                                                                        ,[FName]
                                                                        ,[LName]
                                                                        ,[DOB]
                                                                        ,[Notes]
                                                                        ,[PendingReview] 
                                                       FROM [dbo].[Users]",
                    connection))
                {
                    // Make sure the command object does not already have
                    // a notification object associated with it.
                    command.Notification = null;

                    SqlDependency dependency = new SqlDependency(command);

                    dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);

                    if (connection.State == ConnectionState.Closed)
                        connection.Open();

                    command.ExecuteReader();
                }
            }
        }
        catch (Exception e)
        {
            throw;
        }
    }

private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{   
    SqlDependency dependency = sender as SqlDependency;
    if (dependency != null) dependency.OnChange -= dependency_OnChange;
    //Recall your SQLDependency setup method here.
    SetupDependency();
    JobHub.Show();
}

Я надеюсь, это поможет вам! Если у вас есть еще вопросы, дайте мне знать.

Уведомление об изменении SQL работает для "измененных данных, возвращаемых запросом". Это означает - если вы запрашиваете работу с ID=3 - только изменения в этой записи вызовут уведомление.

Вот хорошие объяснения по этому поводу: SqlDependency OnChange Not Firing

Дело в том, что в примере приложение хочет получить информацию об изменении "любой" записи в таблице. Это работает до сих пор - и (в ссылке выше пункта 1 в ответе) событие запускается ОДИН РАЗ.

Чтобы повторить попытку, вы должны отправить запрос еще раз. Это то, что делает образец - он снова выбирает все данные.

Возможное решение (для достижения того, что вы просите):

A. вызвать запрос с помощью вызова для получения данных - вам не нужно отображать результаты на клиенте - просто выполните запрос.

B. когда происходит событие - повторите запрос - (не отправляя данные клиенту)

C. Вы можете использовать другой (дополнительный) запрос, чтобы узнать, что произошло, или просто использовать результат из B для этого

D.) отправить информацию с сигналом R

Чтобы получить изменения, вам нужно найти способ сравнения данных, поскольку единственная информация, которую предоставляет SQL Server, - это "что-то произошло" (и что), но не то, какие записи были затронуты.

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlnotificationinfo(v=vs.110).aspx

Другая проблема с примером (я просто предполагаю) состоит в том, что если у вас прослушивается несколько клиентов - каждый клиент снова будет "повторять" - это может (я не уверен) во многих подписках на событие.

Так что в следующий раз он сработает несколько раз, что приведет к нескольким запросам...

Таким образом, чтобы расширить приведенный выше пример, вы должны (в дополнение к вышеописанным шагам)

1.) Измените GetData, чтобы он не запускался повторно, если подписка уже сделана

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

3.) Измените схему базы данных, чтобы вы могли легко найти измененные записи - некоторая дополнительная таблица для хранения удаленных записей на тот случай, если вы покажете, что было удалено

Другой подход (без использования SQLChangeNotifications) заключается в том, чтобы хранить код CLR в базе данных. Этот код может вызвать концентратор, который уведомляет клиентов. Но такое решение зависит от нескольких факторов.

а) можно ли запустить клиент signalR внутри SQL Server

б) разрешает ли ваша политика, чтобы сервер БД общался с веб-сервером

c.) позволяет ли ваша политика интеграции SQL CLR

д.)....

Второй подход выглядит проще для меня, поскольку вы можете инициировать отправку из SQL CLR Trigger. Это позволяет отправлять измененные данные без таблиц "лишние столбцы" и "удаленный элемент".

Другие вопросы по тегам