C# 在什么情况下,SQL复制会从c应用程序的MSDTC事务中部分失败(并静默失败)

C# 在什么情况下,SQL复制会从c应用程序的MSDTC事务中部分失败(并静默失败),c#,sql,sql-server,replication,msdtc,C#,Sql,Sql Server,Replication,Msdtc,我们有一个特别奇怪的问题;让我来设定场景。解决方案见下文 为了便于讨论,我们有三个SQLServer2005数据库:Alpha、Beta和Gamma 这些数据库之间定义了复制关系,如下所示: 这三个数据库都有一个名为AnExample的表,其模式相同。复制设置为Alpha是提供者,其他两个数据库是订阅者 使用TransactionScope处理的MSDTC事务的c.NET3.5应用程序正在读取和写入数据库:Alpha和Beta。 此事务中的表示例仅在Alpha上更新。 MSDTC事务已成功提交。

我们有一个特别奇怪的问题;让我来设定场景。解决方案见下文

为了便于讨论,我们有三个SQLServer2005数据库:Alpha、Beta和Gamma

这些数据库之间定义了复制关系,如下所示:

这三个数据库都有一个名为AnExample的表,其模式相同。复制设置为Alpha是提供者,其他两个数据库是订阅者

使用TransactionScope处理的MSDTC事务的c.NET3.5应用程序正在读取和写入数据库:Alpha和Beta。 此事务中的表示例仅在Alpha上更新。 MSDTC事务已成功提交。 一个示例表可能在Alpha中更新,并且该更改立即复制到Gamma中 Beta profiler上未发生任何更改确认数据库上未发生任何活动,SQL日志或事件日志中也未引发任何错误 如果使用相同的凭据重新运行更新Management Studio中示例的相同查询,则成功复制到Beta版 在Beta版上运行MSDTC事务写入另一个表,然后使用主应用程序DAL、连接字符串和配置对Alpha的示例表进行完全相同的写入,也会完全成功地复制到Beta版 这使我们相信,在主应用程序中发生的一些变化并不是孤立发生的

可能的线索/危险因素

我们所看到的成功测试与主应用程序使用的实际查询之间的唯一区别是隔离级别发生了某种变化。在成功的查询中,它被设置为事务隔离级别Read Committed only,而在失败的场景中,它被设置为serializable,尽管没有显式调用来更改代码库或存储过程中的隔离级别

我们确实觉得这有点像是在转移视线,因为在ManagementStudio中以这种隔离级别运行查询再次成功而没有问题。但事实是,这可能是另一个我们尚未发现的问题的症状,这是不同的观点

为了完整起见,这里是无法复制到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*

它有点像一个头巾。我想这是事务复制? 如果是这样,那么日志读取器将从事务日志中获取推送到订阅者的更改,因此这个问题听起来确实很奇怪


我将尝试在发布服务器数据库上运行跟踪,以便您可以观察复制代理的工作。。不确定可能出了什么问题,但可能会有什么东西向你扑来。

所以我们找到了问题所在。如上所述;我们有一个分布式事务,先写到Alpha,然后写到Beta。然后,对Beta的写入成功复制到Gamma,但对Alpha的写入失败。然而,有一个遗漏是,对Alpha的一次写入实际上被复制到Beta,这是大型数据库模式的麻烦。将此写入移动到Beta版意味着复制突然成功

我没有看到通过分布式事务进行的更新不能以多种方式复制的文档,但公平地说,这是一个有点模糊的问题,通过确保复制表上的所有写操作都发生在同一个数据库上就可以简单地解决


希望这对其他人有所帮助。

这可能是无关的,但试着看看这个:谢谢你的建议-我们研究了它,但最终它与你的第一个问题没有区别是的,这是事务复制。尽管我们解决了这个问题——值得一提的是,我们在所有涉及的数据库上都使用了探查器,并且没有发现与失败的复制相关的活动——但它似乎从未尝试过。