我们有一个特别奇怪的问题;让我设置场景。找到的解决方案见下文
我们有三个 SQL Server 2005 数据库,为了论证,我们称之为:Alpha、Beta和Gamma。
这些数据库之间定义了一种复制关系,如下所示:
所有三个数据库都有一个名为“AnExample”的表,具有相同的模式。复制设置为Alpha是提供者,其他两个数据库是订阅者。
- 使用 MSDTC 事务(由 TransactionScope 处理)的 c#.Net 3.5 应用程序同时读取和写入数据库:Alpha 和 Beta。
- 此事务中的表“AnExample”仅在 Alpha 上更新。
- MSDTC 事务成功提交。
- “AnExample”表可能在Alpha中更新,更改立即复制到Gamma
- Beta上没有发生任何变化(分析器确认数据库上没有发生任何活动),SQL 日志或事件日志中也没有出现任何错误
- 使用相同的凭据重新运行在 Management Studio 中更新“AnExample”的相同查询成功(复制到Beta)
- 运行 MSDTC 事务 在Beta上写入另一个表,然后使用主应用程序 DAL、连接字符串和配置的测试应用程序对 Alpha 的“AnExample”表进行完全相同的写入(复制到Beta发生)
这使我们相信主应用程序中发生了一些变化,这些变化不是孤立发生的。
可能的线索/红鲱鱼
我们可以看到的成功测试与主应用程序使用的实际查询之间的唯一区别是隔离级别发生了某种变化。在成功的查询中,它被设置为仅读取已提交的事务隔离级别,而在失败的情况下它被设置为可序列化(尽管没有显式调用来更改代码库或存储过程中的隔离级别)。
我们确实觉得这在某种程度上是一个红鲱鱼,因为在 Management Studio 中使用此隔离级别运行查询再次成功而没有问题。但事实上,这可能是我们尚未发现的另一个问题的征兆。
为了完整起见,这里是无法复制到 Beta(但复制到 Gamma)的查询的设置。
-- network protocol: TCP/IP
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level *serializable*
这有点让人头疼。