65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (1投票)

2019年5月21日

CPOL

2分钟阅读

viewsIcon

5100

当使用 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(通知)
_types_id

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 版本:初始技巧
© . All rights reserved.