MS SQL Server Service Broker 是否响应未提交的数据?





2.00/5 (1投票)
当使用 SqlDependency 时,检测到的更改是否可能导致 SqlDependency 结果中出现 0 行?
引言
在这个技巧中,我展示了 Service Broker 的 PostEventQueryNotification
在更改或插入的行未显示在结果数据表中时如何触发其触发器。
背景
在我的工作中的一些应用程序中,我们结合使用 Service Broker 和 SqlDependency
对象来通知所有连接的客户端关于实体中的更改/添加。当使用高负载时,我们开始在结果中遗漏实体。多亏了日志记录,我们找到了原因。
使用案例
我们有一个 SQL Server 2014 数据库,处于读取已提交模式。
我们使用带有参数值的 SqlDependency 查询。我们只对晚于给定 datetime
的表数据感兴趣。在处理这些数据时,我们从 resultset
中获取最新的 datetime
值,并使用该 datatime
作为参数值再次设置 SqlDependency
。
一个应用程序加载 Excel 文件的内容,这会导致 1,000 条记录被写入数据库。每条记录都作为元数据存储在一个单独的表中,SqlDependency
是为该表设置的。
在日志记录中,我们看到这种情况发生
2019-05-20 16:09:31,254 [37] INFO Services.Notification.DBConnector SqlNotificationEventArgs
: 信息:插入。来源:数据。类型:更改
2019-05-20 16:09:31,312 [37] INFO Services.Notification.DBConnector
DepedencyTable 中的行数:0
2019-05-20 16:09:31,371 [39] INFO Services.Notification.DBConnector SqlNotificationEventArgs
: 信息:插入。来源:数据。类型:更改
2019-05-20 16:09:31,396 [39] INFO Services.Notification.DBConnector
DepedencyTable 中的行数:2
在正常情况下,我们看到
2019-05-20 16:09:31,153 [39] INFO Services.Notification.DBConnector SqlNotificationEventArgs
: 信息:插入。来源:数据。类型:更改
2019-05-20 16:09:31,178 [39] INFO Services.Notification.DBConnector
DepedencyTable 中的行数:1
这触发了我们。
在代码中,我们看到当 resultset
中没有出现行时,我们使用 DateTime.UtcNow
更新了 datetime
值,这就是我们在开始时错过实体的原因。
因此,我们更改了代码,不再更新 datetime
值并设置 SqlDependency
,这就是实体在应用程序中返回的方式。
剩下的一个问题。为什么 SqlDependency
事件在没有记录的情况下被触发?
在 datatable
中,我们看到接下来的 2 行
id | notification(通知) | parent(父级) _business(业务) _id | business _types_id | business _id | facilities(设施) _id | users(用户) _id | client(客户端) _guid | date_(日期) created(创建) | date _received(接收) |
507422 | 1 | 11642 | 8 | 134023 | 1 | 2 | 2100174291 | 2019-05-20 14:09:31.340 | 2019-05-20 14:09:31.340 |
507421 | 1 | 11642 | 8 | 134022 | 1 | 2 | 2100174291 | 2019-05-20 14:09:31.217 | 2019-05-20 14:09:31.217 |
这意味着根据我们的日志记录,SqlDependency
事件在 .254 被触发,但记录在 .340 在数据库中可用,这导致结论:Service Broker 的 PostNotificationQueryEvent
在记录提交到表之前被触发。所以要注意这个特性。
关注点
如果没有日志记录,我们永远不会找到这个原因。
我们测试了应用程序、数据库和通知服务在同一台机器上。因此,不同计算机之间的时间差异在这个测试中不是问题。
历史
- 1.0 版本:初始技巧