TransactionScope超时过早发生?

7
我正在使用TransactionScope进行批量插入和更新。问题是,即使我将TransactionScope的超时时间设置为一小时,我仍然在30分钟的操作中遇到了超时异常。
此外,在出现异常后,似乎随机插入了批处理记录的数量。例如,最后一个操作有12440个插入,超时后表中插入了7673条记录。 SqlConnectionSqlCommand的超时时间都设置为int.MaxValue
我做错了什么?
这是我的代码:
using (TransactionScope transaction = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromHours(1)))
 {
         try
         {
                using (db = new DB())
                {
                //operations here
                }
         }
         catch (Exception ex)
         {
               throw new Exception("DB Error:\r\n\r\n" + ex.Message);
         }

         transaction.Complete();
} // <--- Exception here: Transaction aborted (Inner exception: Timeout)

1
一个更大(可能更重要)的问题是,“为什么几万个INSERT需要这么长时间?” - Mitch Wheat
可能是发生了“命令超时”(从而成为“事务范围超时”的假问题)吗?这可以解释“随机性”,考虑到记录被插入得如此之慢……我看到问题上说设置为MaxValue,但我怀疑……问题并不像看起来那样。 - user166390
@Mitch:由于连接速度非常慢,所以它是一个接一个地完成的。因此有一个一小时的超时限制 :) @pst:插入是在循环中完成的。每次迭代都会设置CommandText并执行。因此它不会等待一个大SQL的结果,我怀疑这不是一个命令超时。此外,我使用了一个非常简单的DAL,只有SqlConnection和SqlCommand,我没有看到任何其他超时。如果您有任何其他建议,我很乐意检查? - dstr
2个回答

8
如果您的事务在10分钟后失败了,那么您可能正在撞上设置在machine.config中的Transaction Manager Maximum Timeout。如果我没记错的话,如果您尝试设置一个超过最大值的超时时间,则您的设置将被忽略。尝试增加machine.config中的值,看看是否有助于解决问题。
关于随机提交,您是否在连接字符串上设置了Transaction Binding=Explicit Unbind?默认值为Transaction Binding=Implicit Unbind。来自MSDN

隐式解绑会导致连接在事务结束时与之分离。分离后,连接上的其他请求将以自动提交模式执行。在事务处于活动状态时,不检查System.Transactions.Transaction.Current属性执行请求。事务结束后,将以自动提交模式执行其他请求。

基本上,当事务超时时,所有插入操作都将回滚到该点,但使用相同连接进行的任何其他插入操作都将在自动提交模式下执行,其中每个插入语句都会立即提交。听起来与您看到的情况相似(但不看完整的代码/重现很难知道)。

2
我建议您尝试使用SqlBulkCopy类,这样可以提高速度,也可能消除长时间超时的需要。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接