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

时间:2009-04-30 14:55:40

标签: c# sql sql-server replication msdtc

我们有一个特别奇怪的问题;让我设置场景。 找到的解决方案见

我们有三个SQL Server 2005数据库,出于参数的名称: Alpha Beta Gamma

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

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

  1. 使用MSDTC事务(由TransactionScope处理)的c#.Net 3.5应用程序正在读取和写入数据库:Alpha和Beta。
  2. 此交易中的表格“AnExample”仅在Alpha上更新。
  3. MSDTC事务成功提交。
  4. “AnExample”表可能会在 Alpha 中更新,并且更改会立即复制到 Gamma
  5. Beta 没有发生变化(探查器确认数据库上没有活动),SQL日志或事件日志中也没有出现任何错误
  6. 重新运行使用相同凭据在Management Studio中更新“AnExample”的相同查询成功(复制到 Beta
  7. 运行MSDTC事务写入 Beta 上的另一个表,然后使用主应用程序DAL,连接字符串和配置对Alpha的“AnExample”表进行完全相同的写入测试应用程序也完全成功(复制到 Beta
  8. 这使我们相信主要应用程序中发生了一些不会孤立发生的变化。

    可能的线索/红色鲱鱼

    我们在成功测试和主应用程序使用的实际查询之间可以看到的唯一区别是隔离级别已经以某种方式发生了变化。在成功的查询中,它仅设置事务隔离级别Read Committed,而在失败的方案中将其设置为可序列化(尽管没有显式调用来更改代码库或存储过程中的隔离级别)。

    我们确实认为这有点像红色鲱鱼,因为在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*
    

    这是一个头脑风暴。

2 个答案:

答案 0 :(得分:0)

我认为这是事务复制? 如果是这样,日志阅读器会从事务日志中收集推送到订阅者的更改,因此问题确实听起来很奇怪。

我会尝试在发布者数据库上运行跟踪,这样你就可以看到复制代理的功能了......不确定可能出现什么问题,但也许会有什么东西会突然出现。

答案 1 :(得分:0)

所以我们发现了什么似乎是问题。如上所述;我们有一个分布式事务,写入 Alpha 然后 Beta 。然后,对 Beta 的写入成功复制到 Gamma ,它会无声地失败到 Alpha 。但是有一个遗漏,其中一个对 Alpha 的写入实际上被复制到 Beta (大型数据库模式的麻烦)。将此写入移动到 Beta 意味着突然复制成功。

我没有看到它记录了通过分布式事务进行的更新无法通过单一方式进行复制,但为了公平起见这是一个有点模糊的问题,只需通过确保复制表上的所有写操作都发生在同一个数据库中即可解决。

希望这有助于其他人。