当前位置:  开发笔记 > 后端 > 正文

默认交易超时

如何解决《默认交易超时》经验,为你挑选了4个好方法。

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

 
    
  

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

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

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

总结一下:

是否无法混合配置设置和TransactionOptions的使用

如果没有,是否有任何方法可以在运行时提取配置设置,并使用它来设置Timeout属性

[编辑]或设置默认隔离级别而不使用TransactionOptions

Ronald.. 47

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

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

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
};


Zach Bonham.. 46

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

如果使用TransactionOption并指定一个Timeout值,则该值将用于system.transactions/defaultTimeout值.

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

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

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


    

随着maxTimeout集,不管你指定什么超时值,最大值将被限制到maxTimeout值.默认的maxTimeout是00:10:00或10分钟,因此您实际上不会在事务上有无限超时.

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

   var connectionString = "Server=.;Database=master;Trusted_Connection=True;";

            using (var scope = new TransactionScope(TransactionScopeOption.Required))
            {
                using (var conn = new SqlConnection(connectionString))
                {
                    conn.Open();
                    var sqlTransaction = conn.BeginTransaction(System.Data.IsolationLevel.Serializable);

                    // do database work
                    //
                    sqlTransaction.Commit();


                }

                // do other work..
                //

                scope.Complete();

            }

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



1> Ronald..:

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

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

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> Zach Bonham..:

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

如果使用TransactionOption并指定一个Timeout值,则该值将用于system.transactions/defaultTimeout值.

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

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

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


    

随着maxTimeout集,不管你指定什么超时值,最大值将被限制到maxTimeout值.默认的maxTimeout是00:10:00或10分钟,因此您实际上不会在事务上有无限超时.

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

   var connectionString = "Server=.;Database=master;Trusted_Connection=True;";

            using (var scope = new TransactionScope(TransactionScopeOption.Required))
            {
                using (var conn = new SqlConnection(connectionString))
                {
                    conn.Open();
                    var sqlTransaction = conn.BeginTransaction(System.Data.IsolationLevel.Serializable);

                    // do database work
                    //
                    sqlTransaction.Commit();


                }

                // do other work..
                //

                scope.Complete();

            }

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



3> Raghu Dodda..:

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

DefaultTimeOut由第一规则确定从下满足:

如果构造函数有TimeSpan参数,则DefaultTimeout是该参数

如果构造函数有TransactionOption参数,则DefaultTimeout为transactionOption.TimeOut

如果构造函数有TransactionScopeOption参数,则DefaultTimeout为scopeOption.TimeOut

如果构造函数没有timeout参数,则DefaultTimeout是应用程序或Web配置文件中指定的值.

否则,DefaultTimeOut为1分钟.

所述MaxTimeOut为10分钟,除非在machine.config指定另一值.

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

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

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

也可以定义MaxTimeOut在应用程序/ Web配置文件,如果在machine.config相关的部分被覆盖(注意allowDefintion的价值观和allowExeDefinition属性):


    

为了快速参考,这里是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);



4> Mike Two..:

使用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;

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有