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

7

众所周知,根据这个答案,TransactionScope的maxTimeout是在machine.config中定义的。

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


除了这个问题,我还有一个疑问 - 如果我在web.config中定义了这个,它会覆盖machine.config吗? - Chandan Kumar
@uɐpuɐɥƆ 我认为你所寻找的内容在此答案中的链接线程中有所解释:[https://dev59.com/_Wct5IYBdhLWcg3wgNYy#12941902]。 - default
@uɐpuɐɥƆ 你不能添加它。项目将不会加载此配置。 - Backs
1
maxTimeout限制需要作为机器级别的设置,而不是应用程序级别的设置,因为事务范围可以调节应用程序之间的交易。如果两个应用程序为maxTimeout提供了不同的设置,则会产生混淆,不知道应该使用哪个限制。 - Sergey Kalinichenko
@dasblinkenlight 当两个服务器通信时,分布式事务怎么处理? - Backs
1个回答

4

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

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

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

  • 几天前,我也在寻找可能的覆盖方式,我发现以下两个解决方案对我有效。这里是包含完整文章的链接:链接

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

<system.transactions>
<machineSettings maxTimeout="00:20:00" />
</system.transactions>
  • Although this approach changes a machine wide setting, it does not change the machine wide maxtimeout for the machine. One will be able to retain whatever value is set for the maxTimeout and one will be able to set whatever value is fit for the specific application in the app.config. Thus, each app can override the machine wide maxTimeout setting and set its own maxTimeout.

    2. Override in code :

  • This approach uses reflection API to accesses private data members of Microsoft classes. If you are not familiar with reflection API then you can refer to this Link
  • It doesn't require modifying the machine.config, it doesn't open up other application to possible DOS situations and it circumvents any company policy. Below is the code that does this:

    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);
            }
        }
    
  • To use it call the following before creating the TransactionScope object:

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

机器配置文件的路径

  • 32位系统

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

  • 64位系统

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


嗨,是的,我使用反射解决方案。感谢完整的答案。 - Backs
嗨@Backs,我也使用了相同的解决方案[使用反射],因为我们客户的基础设施团队不希望在machine.config文件中进行任何更改。这对我也起作用了。 - Intimate
1
在 .NET Core 中,这些字段被命名为 s_cachedMaxTimeouts_maximumTimeout - wodzu

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