Service Broker 不会通知取消订阅和重新连接到 SqlDependency.OnChange 事件之间发生的更改

Service Broker does not notify about changes taking place between unsuscribing and re-wiring to the SqlDependency.OnChange event

我有这个代码:

    public partial class Form1 : Form
    {
        private string _connectionString = @"Data Source=(local)\SQLEXPRESS; Initial Catalog=MyDatabase; User Id=sa; Password=test";
        //private SqlCommand _command;
        //private SqlConnection _connection;
        public Form1()
        {
            InitializeComponent();
        }

        public void Notify(Object sender, SqlNotificationEventArgs args)
        {
            var obj = sender as SqlDependency;
            obj.OnChange -= Notify;

            Listen();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SqlDependency.Start(_connectionString,"CacheQueue");
            Listen();
        }

        private void Listen()
        {
            using (var _connection = new SqlConnection(_connectionString))
            {
                _connection.Open();

                using (SqlCommand command = new SqlCommand(
                    @"SELECT [C1] ,[C2],[C3] FROM [dbo].[Table]",
                    _connection))
                {

                    SqlDependency dependency = new SqlDependency(command, "Service=CacheService", 0);

                    dependency.OnChange += new OnChangeEventHandler(Notify);

                    command.ExecuteNonQuery();
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            SqlDependency.Stop(_connectionString, "CacheQueue");
        }
    }

我正在使用 SQL Server 2008 Express Edition,并且正在我的本地计算机上进行测试。在 SQL 服务器中,我执行了以下语句:

ALTER DATABASE MyDatabase SET ENABLE_BROKER;

CREATE QUEUE CacheQueue;

CREATE SERVICE CacheService
  ON QUEUE CacheQueue
([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification]);

如果我在收到第一个通知和重新连接到 OnChange 事件之间对 table "Table" 执行多个更新,我不会收到任何其他通知。

例如,假设我在 SQL 服务器中 运行 这条语句:

UPDATE [Table] 
SET C1 = 'aaaa'
WHERE Id = 7 -- an existing Id

之后,我收到通知并触发了 "Notify" 事件处理程序。但是,如果我在断点处停留并返回 SQL 并在同一 table 上执行其他 DML 语句,则我不会收到任何通知。我的期望是,在重新连接到 OnChange 事件后,我将能够获得同时发生的所有更改。他们不是在 Service Broker 中排队吗?我怎样才能实现这种行为?

这实际上与Service Broker无关。一切都是为了 Query Notifications, an unrelated feature that uses Service Broker to deliver its notifications. Please read The Mysterious Notification 了解我们在说什么。

您必须了解查询通知的作用:它允许在查询结果更改 时通知客户端应用程序。非常具体地说,它 不是 更改跟踪机制。对于更改跟踪,请使用 Change Tracking or Change Data Capture.

因此,您的期望是没有根据的。在您提交查询后,您应该会收到一次通知。仅此而已。