事务范围超时10分钟

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

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

您好,您可以在配置文件中validationmaxTimeout,如果您在web.config或app.config上没有此部分

validation您的machine.config

      

调整值

进一步澄清:

Transaction Scope使用Machine配置设置作为最大超时。 默认机器超时为10分钟。

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

     

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

将应用配置设置为1小时:

    

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

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

要允许事务花费超过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); } 

用法:

 using (var ts = CreateTransactionScope(TimeSpan.FromMinutes(20))) { DoLongCode(); ts.Complete(); } 

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

他们不工作,因为你正试图改变超时是错误的背景。

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

你应该有这些背景:

  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 

考虑完全信任环境,您可以使用reflection覆盖最大超时:

  //Get machineSettings session var machineSettings = (System.Transactions.Configuration.MachineSettingsSection)ConfigurationManager.GetSection("system.transactions/machineSettings"); //Allow modifications var bReadOnly = (typeof(ConfigurationElement)).GetField("_bReadOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); bReadOnly.SetValue(machineSettings, false); //Change max allowed timeout machineSettings.MaxTimeout = TimeSpan.MaxValue; using (var t = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(1,0,0))) { //1 hour transaction //... } 

我解决了修改“ 物理文件machine.config的问题


1.您必须本地化文件:

  • 32位: C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ Config \ machie.config
  • 64位: C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Config \ machine.config

2.您必须添加以下代码:

    

您可以在项目中添加此代码以延长事务时间。

 // This is used for set the transaction timeout to 40 minutes. Type oSystemType = typeof(global::System.Transactions.TransactionManager); System.Reflection.FieldInfo oCachedMaxTimeout = oSystemType.GetField("_cachedMaxTimeout", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); System.Reflection.FieldInfo oMaximumTimeout = oSystemType.GetField("_maximumTimeout", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); oCachedMaxTimeout.SetValue(null, true); oMaximumTimeout.SetValue(null, TimeSpan.FromSeconds(2400));