为什么在 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
正如我们从 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