为什么在 machine.config 中定义了 TransactionScope 超时?

Why TransactionScope timeout is defined in machine.config?

正如我们从 this 的回答中得知的那样,TransactionScope 的 maxTimeout 在 machine.config.

中定义

那么,是什么原因呢?为什么我们不能在 app.config (web.config) 中或仅在代码中覆盖它?

为什么在machine.config中定义TransactionScope超时?

  • machine.config 文件存储机器级配置设置。 Machine.config 设置适用于驻留在服务器上的所有 Web 应用程序。 TransactionScope 超时值是任何人都希望在所有 Web 应用程序中保持统一的值。
  • 这样做的一个好处是,当您想要更改 IIS 中托管的所有应用程序的事务范围超时值时,您可以通过在一个地方更改值来实现。但是,这并不意味着您不能在 app.config 或 web.config 文件中覆盖它。有一种方法可以覆盖它。

为什么我们不能在 app.config (web.config) 中或仅在代码中覆盖它?

  • 几天前,我也在寻找可能的覆盖方法,我在下面找到了两个对我有用的解决方案。这里是 link,其中包含关于此的完整文章。 Link

1。在 web.config / app.config 文件中覆盖: - 在 machine.config 文件中,在 "system.transactions" 节组节点下,在 "machineSettings" 节节点中,有一个名为 'allowExeDefinition' 的属性,默认值为 "MachineOnly"。将此值更改为 "MachineToApplication"。这允许将以下内容添加到应用程序的 web.config 并覆盖机器范围的设置:

<system.transactions>
<machineSettings maxTimeout="00:20:00" />
</system.transactions>
  • 虽然这种方法改变了机器范围的设置,但它并没有改变机器的机器范围的最大超时。可以保留为 maxTimeout 设置的任何值,也可以设置适合 app.config 中特定应用程序的任何值。因此,每个应用程序都可以覆盖机器范围的 maxTimeout 设置并设置自己的 maxTimeout。

    2。在代码中覆盖:

  • 此方法使用反射 API 来访问 Microsoft 类 的私有数据成员。如果你对反射不熟悉API那么你可以参考这个Link
  • 它不需要修改 machine.config,它不会打开其他应用程序以应对可能的 DOS 情况,并且它规避了任何公司政策。下面是执行此操作的代码:

    public static class TransactionManagerHelper
        {
            public static void OverrideMaximumTimeout(TimeSpan timeout)
            {
                //TransactionScope inherits a *maximum* timeout from Machine.config.  There's 
                  no way to override it from
                //code unless you use reflection.  Hence this code!
                //TransactionManager._cachedMaxTimeout
                var type = typeof(TransactionManager);
                var cachedMaxTimeout = type.GetField("_cachedMaxTimeout", 
                BindingFlags.NonPublic | BindingFlags.Static);
                cachedMaxTimeout.SetValue(null, true);
    
                //TransactionManager._maximumTimeout
                var maximumTimeout = type.GetField("_maximumTimeout", BindingFlags.NonPublic | BindingFlags.Static);
                maximumTimeout.SetValue(null, timeout);
            }
        }
    
  • 要使用它,请在创建 TransactionScope 对象之前调用以下命令:

    TransactionManagerHelper.OverrideMaximumTimeout(TimeSpan.FromMinutes(5));

Machine.config

的路径
  • 32 位系统

%windir%\Microsoft.NET\Framework[版本]\config\machine.config

  • 64 位系统

%windir%\Microsoft.NET\Framework64[版本]\config\machine.config