【问题标题】:TransactionScope timeout weirdness with TransactionScopeOption.RequiresNewTransactionScope 超时怪异与 TransactionScopeOption.RequiresNew
【发布时间】:2009-04-27 10:22:00
【问题描述】:

这里发生了一些非常奇怪的事情。

我刚刚在我正在调试的一些遗留代码周围添加了一个事务范围,以确保我正在做的摆弄不会被提交。

这工作了两次,然后说:

"The transaction manager has disabled its support for remote/network transactions."

在工作/非工作之间没有任何代码更改或重建(字面意思是连续 3 个 F5 [网络应用程序])。这是连接到删除数据库服务器的本地代码。

因此,不同项目中完全独立的代码将超时。如果我从此代码中删除 transactionScopes,它运行良好,但在它们到位时它会超时。我已经尝试过本地 SQL 服务器和远程 SQL 服务器,它们都在 transactionScope 内超时。

这到底是怎么回事?

编辑:我发现将我的 TransactionScopes 更改为:

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))

using (var scope = new TransactionScope())

防止问题:s

这是什么意思?

【问题讨论】:

  • 你能给我们看看代码吗...
  • 不容易,我试图创建一个简单的例子来重现它。敬请期待

标签: c# transactionscope


【解决方案1】:

两者的区别:

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))

using (var scope = new TransactionScope())

第二个重用现有(环境)事务,而第一个在旧事务中创建新事务。

事务中的这个事务需要分布式事务协调器。

您的错误可能有以下三个原因:

  • MSDTC 未运行
  • 您的数据库位于另一台计算机上,并且 Windows 配置为不允许来自网络的事务。
  • 您的数据库位于另一台计算机上,并且 SQL Server 配置为不允许来自网络的事务

【讨论】:

  • +1 指出“new TransactionScope()”等价于“new TransactionScope(TransactionScopeOption.Required)” - 它可以发挥重要作用。
【解决方案2】:

我相信当错误发生时,框架正试图将原来的“轻量级”(即 DBMS)事务提升为“分布式”事务。管理分布式事务的 MSDTC(分布式事务协调器)服务要么未运行,要么无法工作。

这通常发生在一个逻辑事务跨越两个(或多个)数据库连接时。当然,在您的情况下,(显然)只有一个 DBMS 连接。我猜通过强制一个新的、独立的事务范围,你也强制框架使用分布式事务。

【讨论】:

【解决方案3】:

老问题,但我遇到了同样的问题,所以这里提供了解决多种问题的简单信息。

如果您可以从 TransactionScopeOption.RequiresNew 更改为 TransactionScopeOption.Required 检查您是否真的需要明确嵌套事务的行为并考虑通过阅读 this MSDN article 明确设置事务范围的类型。可能您的问题是锁定资源的新事务的数量,这就是问题“奇怪”的原因。

此外,您应该检查以下信息:

The default transaction scope is considered harmful

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))

默认你设置:

  1. IsolationLevel as Serializable(考虑使用IsolationLevel.ReadCommitted
  2. 超时到一分钟(考虑使用TransactionManager.MaximumTimeout

使用这两个选项和TransactionScopeOption.RequiresNew,您应该会遇到死锁。

这里是新代码:

new TransactionScope(TransactionScopeOption.Required, 
    new TransactionOptions 
    {
        IsolationLevel = IsolationLevel.ReadCommitted,
        Timeout = TransactionManager.MaximumTimeout
    }
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多