事务范围超时10分钟

Pat*_*ick 28 c# entity-framework transactions transactionscope

TransactionScope在C#中长期运行.我告诉范围它应该有很长的时间跨度,但我仍然会超时.什么可能导致这个?

TransactionOptions transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
transactionOptions.Timeout = TimeSpan.MaxValue;
using (var ts = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{ 
    DoLongCode();
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*der 33

进一步澄清:

事务范围使用计算机配置设置作为最大超时.默认机器超时为10分钟.

将机器配置设置为2小时:

      <system.transactions>
        <machineSettings maxTimeout="02:00:00"/>
      </system.transactions> 
Run Code Online (Sandbox Code Playgroud)

可以将app.config或web.config缩减为超时但不能用于超出计算机配置超时.

将app config设置为1小时:

<system.transactions>
     <defaultSettings timeout="01:00:00" />
</system.transactions>
Run Code Online (Sandbox Code Playgroud)

此外,我们在达到限制时没有收到任何异常,也没有跟踪或事件日志记录.

此外,TransactionScope对象具有构造函数重载,允许您指定超时,但我不确定如何处理.


Jup*_*aol 25

要允许事务超过10分钟,而无需更改machine.config,请使用此代码

    private void SetTransactionManagerField(string fieldName, object value)
    {
        typeof(TransactionManager).GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, value);
    }

    public TransactionScope CreateTransactionScope(TimeSpan timeout)
    {
        SetTransactionManagerField("_cachedMaxTimeout", true);
        SetTransactionManagerField("_maximumTimeout", timeout);
        return new TransactionScope(TransactionScopeOption.RequiresNew, timeout);
    }
Run Code Online (Sandbox Code Playgroud)

用法:

using (var ts = CreateTransactionScope(TimeSpan.FromMinutes(20)))
{ 
    DoLongCode();
    ts.Complete();
}
Run Code Online (Sandbox Code Playgroud)

基于这篇文章,文章 的代码最初粘贴在这里.答案中的代码现在已经过重构和简化.

  • 对我来说,这些字段被命名为 s_cachedMaxTimeout 和 s_maximumTimeout,因此我将其更改为尝试任一字段名称并使用有效的字段名称。这仍然是一种黑客攻击(如原始文章中所述),但有时确实没有其他选择。 (2认同)

Agh*_*oub 21

如果您在web.config或app.config上没有此部分,则可以在配置文件中验证maxTimeout

验证您的machine.config

<configuration> 
  <system.transactions>
    <machineSettings maxTimeout=""/>
  </system.transactions>
</configuration> 
Run Code Online (Sandbox Code Playgroud)

调整值

  • @jpierson我真的很讨厌微软.当只有这个需要特殊行为的应用程序时,为什么要更改系统设置.他们有没有想过像"LocalDB","SQLCe","SQLite"这样的独占模式本地数据库?没有! (5认同)
  • 根据MSDN上的此线程,您无法覆盖web.config或app.config文件中的maxTimeout值.http://social.msdn.microsoft.com/Forums/da-DK/windowstransactionsprogramming/thread/584b8e81-f375-4c76-8cf0-a5310455a394 (3认同)
  • 在Windows Azure中无法更改,10分钟是最大超时. (2认同)

小智 5

它们不起作用,因为您尝试更改超时的上下文错误。

尝试将其更改为更接近有效查询。

您应该具有以下上下文:

    using (var txn = new TransactionScope(
                            TransactionScopeOption.Required,
                            new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted, Timeout = new TimeSpan(1,0,0) })) // 1 hour or wathever, will not affect anything
                    {

                        using (SqlConnection connection = new SqlConnection(ConnectionString))
                        {
                            int ct = connection.ConnectionTimeout // (read Only, this is the effective default timeout is 15 seconds)
                            connection.Open();

                            SqlCommand select = new SqlCommand(sql.query, connection); // bind to server
                            select.CommandTimeout = 0; // <-- here does apply infinite timeout
SqlDataReader reader = select.ExecuteReader(); // never stop
Run Code Online (Sandbox Code Playgroud)