默认交易超时

时间:2009-08-28 16:45:18

标签: .net configuration transactions timeout

我曾经使用 TransactionOptions.Timeout 来设置事务超时,但已决定使用配置方法来简化维护:

 <system.transactions>
    <defaultSettings timeout="00:01:00" />
  </system.transactions>

当然,在把它放入之后,我想测试它是否正常工作,所以将超时时间减少到5秒,然后运行一个持续时间超过这个的测试 - 但事务似乎没有中止!如果我调整测试以将TransactionOptions.Timeout设置为5秒,则测试按预期工作

调查后我认为问题似乎与TransactionOptions.Timeout有关,即使我不再使用它。

我仍然需要使用TransactionOptions,所以我可以设置IsolationLevel,但我不再设置Timeout值,如果我在创建它后查看此对象,则超时值为00:00:00,相当于无穷大。这是否意味着我的配置文件中设置的值被忽略了?

总结:

  • 是否无法混合配置 设置和使用 TransactionOptions
  • 如果没有,是吗? 任何提取配置设置的方法 在运行时,并使用它来设置 超时属性
  • [编辑]或设置默认隔离级别,而不使用TransactionOptions

6 个答案:

答案 0 :(得分:46)

您可以混合使用system.transaction配置设置和使用TransactionOption类,但有些事情需要注意。

  

如果您使用TransactionOption和   指定Timeout值,即该值   将被用于   System.Transactions的/ defaultTimeout   值。

以上是我认为问题的症结所在。您正在使用TransactionOption指定隔离级别,并且作为副作用,您将获得无限超时值,因为无限是{的默认超时值{1}}如果未指定。虽然,我不太清楚为什么会这样......默认为默认的事务超时是有意义的。

您可以实现自己的TransactionOptions帮助程序类,其中包括从app.config读取的默认值(如果找到)或默认为可以使用的TransactionOption类的合理值。

在任何情况下,您仍然可以使用 system.transaction / machineSettings / maxTimeout 值来限制此值。这是一个管理设置,只能通过machine.config进行配置。如果你从app / web.config尝试它,你会得到一个ConfigurationException。

TransactionOption

设置 maxTimeout 后,无论您指定的超时值如何,最大值都将限制为maxTimeout值。默认的maxTimeout是00:10:00或10分钟,因此您实际上不会在事务上有无限超时。

您还可以在事务中使用的数据库连接上设置事务IsolationLevel 显式。像这样的东西?

<system.transactions>
    <machineSettings maxTimeout="00:00:30" />
</system.transactions>

在测试中,您可能需要确保重建以便重新生成app.config。在我的测试中,似乎我需要终止* .vshost.exe进程,以便它获取system.transaction配置设置更改 - 尽管我觉得这可能是一个侥幸。只是fyi ..

答案 1 :(得分:46)

您可以使用TransactionManager.DefaultTimeout从配置中获取(验证的)默认超时。

TransactionOptions是一个封装超时和隔离级别的结构。使用默认构造函数初始化struct时,它总是将struct成员初始化为其默认值:

TransactionOptions transactionOptions = new TransactionOptions();
transactionOptions.Timeout == default(TimeSpan); // TimeSpan.Zero
transactionOptions.IsolationLevel == default(IsolationLevel); // IsolationLevel.Serializable

如果要指定IsolationLevel并使用默认超时:

new TransactionOptions()
{
    IsolationLevel = IsolationLevel.Serializable, // Use whatever level you require
    Timeout = TransactionManager.DefaultTimeout
};

答案 2 :(得分:11)

Per Reflector,使用TransactionScope的构造函数设置事务超时的基本规则如下:

DefaultTimeOut 由满足以下条件的第一条规则决定:

  • 如果构造函数具有TimeSpan参数,则DefaultTimeout是该参数
  • 如果构造函数具有TransactionOption参数,则DefaultTimeout为transactionOption.TimeOut
  • 如果构造函数具有TransactionScopeOption参数,则DefaultTimeout为scopeOption.TimeOut
  • 如果构造函数没有timeout参数,则DefaultTimeout是应用程序或Web配置文件中指定的值。
  • 否则,DefaultTimeOut为1分钟。

除非在machine.config中指定了其他值,否则 MaxTimeOut 为10分钟。

事务的有效超时小于MaxTimeOut和DefaultTimeOut,大于零。如果MaxTimeOut和DefaultTimeOut都为零,则有效超时是由long.MaxValue(无穷大)表示的刻度数。

如果TransactionScope实例未创建新事务,或者因为事务被传递到其构造函数中,或者因为事务范围选项不需要它(例如,当存在环境事务并且TransactionScopeOption是必需),但仍在构造函数中传递timeOut参数,启动计时器。超时期限过去后,将调用基础事务的TimeOut()方法。在这种情况下不使用DefaultTimeOut和MaxTimeOut属性。

如果transactionScopeOption == TransactionScopeOption.Supress,则忽略超时并且无效。

如果覆盖了machine.config中的相关部分,也可以在app / web配置文件中定义MaxTimeOut(请注意allowDefintion和allowExeDefinition属性的值):

<sectionGroup name="system.transactions" type="System.Transactions.Configuration.TransactionsSectionGroup, System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null">
    <section name="defaultSettings" type="System.Transactions.Configuration.DefaultSettingsSection, System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null"/>
    <section name="machineSettings" type="System.Transactions.Configuration.MachineSettingsSection, System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null" allowDefinition="MachineToApplication" allowExeDefinition="MachineToApplication"/>
</sectionGroup>

为了快速参考,这里是TransactionScope构造函数:

public TransactionScope(Transaction transactionToUse, TimeSpan scopeTimeout, EnterpriseServicesInteropOption interopOption);
public TransactionScope(TransactionScopeOption scopeOption, TransactionOptions transactionOptions, EnterpriseServicesInteropOption interopOption);
public TransactionScope(TransactionScopeOption scopeOption, TransactionOptions transactionOptions);
public TransactionScope(TransactionScopeOption scopeOption, TimeSpan scopeTimeout);
public TransactionScope(Transaction transactionToUse, TimeSpan scopeTimeout);
public TransactionScope(TransactionScopeOption scopeOption);

答案 3 :(得分:6)

使用TransactionOptions时,将忽略配置文件设置。在大多数情况下,创建TransactionScope将创建CommittableTransaction的实例。 CommittableTransaction的no arg构造函数将使用配置文件设置作为其默认超时。采用TransactionOptions或TimeSpan的TransactionScope构造函数将调用CommittableTransaction类的重载之一而不是no arg版本。因此,如果您想使用该值,您必须自己从配置文件中获取它。

当我遇到这个时,我将以下代码放在一个TransactionOptionsFactory类中。


Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSectionGroup sectionGroup = configuration.GetSectionGroup("system.transactions");
DefaultSettingsSection defaultSettings = (DefaultSettingsSection) sectionGroup.Sections["defaultSettings"];
TransactionOptions options = new TransactionOptions();
options.Timeout = defaultSettings.Timeout;
options.IsolationLevel = IsolationLevel.ReadCommitted;

答案 4 :(得分:2)

void Main()
{
    var maximumTimeout = TransactionManager.MaximumTimeout;//This step is necessary to init _maximumTimeout value, 

    FieldInfo fieldInfo = typeof(TransactionManager).GetFields(BindingFlags.NonPublic | BindingFlags.Static).Single(item => item.Name == "_maximumTimeout");
    var customMaximumTimeout = TimeSpan.FromHours(1);
    fieldInfo.SetValue(null, customMaximumTimeout);
    maximumTimeout = TransactionManager.MaximumTimeout;

    Console.WriteLine(maximumTimeout);//01:00:00
    // use TransactionScope
}

答案 5 :(得分:1)

把我当前的想法放下来:

  • 无法混合配置设置和使用TransactionOptions
  • 在运行时提取配置设置的唯一方法是将app.config作为XML文件读取
  • 默认隔离级别只能通过事务选项完成,或者使用属性在WCF中的服务级别完成