C#分布式事务的超时处理实例分析

 更新时间:2015年03月30日 16:24:38   作者:码农小牛  
这篇文章主要介绍了C#分布式事务的超时处理,以实例形式较为详细的分析了C#分布式事务的超时处理相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下

本文实例讲述了C#分布式事务的超时处理的方法。分享给大家供大家参考。具体分析如下:

事务是个很精妙的存在,我们在数据层、服务层、业务逻辑层等多处地方都会使用到。

在这里我只说下TransactionScope这个微软推荐使用的隐式事务。它是从Framework 2.0开始引入的一个事务管理类,在使用隐式事务时,事务完成前 程序应调用TransactionScope的Complete()方法,将事务提交,然后利用Dispose()释放事务对象。若执行期间出现错误,事务将自动回滚。

比如:

using (ransactionScope scope = new TransactionScope())
{
    //to do something
    scope.Complete();
}

在这里个人建议用using来创建,因为using实现了IDispose接口,它会隐式的调用TransactionScope对象的Dispose方法,即使发生异常时也是如此,能确保在事务结束或者异常的时候也能正确的释放资源。其实我们反编译一下,它的内部实现就是一个try...finally代码块,这样也就不难理解using的作用了。

说主题,在某地市的某库升级中,为避免程序运行中产生脏数据以及数据更新不一致导致的重复同步情况,在可能产生上述问题的考虑下,我用这个TransactionScope来对上述的操作进行事务处理。在本机的测试环境中,运行结果是正常的,当然这个运行正常的前提是数据量较小的情况下,我每次只对一条或者十几条数据的不同表进行insert和update。然而部署到生产环境针对真实数据运行之后,发现这个事务总是回滚,一直无法正常提交。程序也就没法正常跑起来。因为生产环境中的数据有60W左右,insert一次、update一次,最后再insert一条同步语句,前2个操作都是比较耗时的。我切换回测试环境调试了一下,逐行运行,发现当执行完第一个insert之后,执行第二个update时发生异常了。这个异常由TransactionScope抛出,异常提示是:事务已中止。这个错误,在数据量小的情况下不会发生,数据量大一些就出现了,这个是不是和事务处理的时间长短有关呢?因为我明显感觉到在这次调试的时候,执行的时间比之前数据量只有一条的时候长了很多,至少花费1分钟以上。于是google一下,验证了我的想法。

TransactionScope有些重载函数是可以接受TimeSpan类型的值,这个就是事务的超时时间了。当事务实现隔离的时候,事务范围内的资源将会被锁定,如果一些事务长期占有资源,那将很容易造成死锁,为了避免这个问题,TransactionScope事务会定义一个超时限制,这个超时默认值为60秒。如果事务超过此时间,即使没有发生异常,也会自动中止。上面问题的原因算是找到了,知道了原因,那么也就很好解决了。我们可以在Web.Config 中配置:

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

或者在using的时候就定义好超时时间:

复制代码 代码如下:
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required,
new TimeSpan(0, 5, 0)))

或者先初始化事物行为的附加信息,然后定义超时时间:

复制代码 代码如下:
TransactionOptions tOpt = new TransactionOptions();
tOpt.IsolationLevel = IsolationLevel.ReadCommitted;
//设置TransactionOptions模式
tOpt.Timeout = new TimeSpan(0, 5, 0);
// 设置超时时间为5分钟
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, tOpt))

我这里定义的是5分钟,其实整个过程处理起来也就第一次处理历史数据需要1到2分钟时间,以后每天只需处理几十条数据,这个时间基本是秒级别的。

这里说明下, 超时时间如果设置为0时表示超时无限长。无限长的设置主要对调试有用,调试过程中可能要逐步通过代码来隔离业务逻辑中的问题,并且在尝试确定问题期间不希望所调试的事务超时。在所有其他情况下使用无限长的超时时一定要格外小心,因为它会覆盖防止事务死锁的保护。

希望本文所述对大家的C#程序设计有所帮助。

相关文章

  • Base64编码解码原理及C#编程实例

    Base64编码解码原理及C#编程实例

    这篇文章主要介绍了Base64编码解码原理及C#编程实例,本文讲解了Base64编码由来、Base64编码原理、C#编程实现,需要的朋友可以参考下
    2014-10-10
  • C#实现根据银行卡卡号判断银行名

    C#实现根据银行卡卡号判断银行名

    这篇文章主要介绍了C#实现根据银行卡卡号判断银行名,是从其他网友的java程序改编而来,有需要的小伙伴可以参考下。
    2015-07-07
  • C#基于COM方式读取Excel表格的方法

    C#基于COM方式读取Excel表格的方法

    这篇文章主要介绍了C#基于COM方式读取Excel表格的方法,涉及C# COM组件的调用与Excel表格的使用技巧,需要的朋友可以参考下
    2016-07-07
  • C# 基于NPOI操作Excel

    C# 基于NPOI操作Excel

    最近遇到一个数据导入的需求,语言是.net framework 4.7的C#。但是,这次主要探讨NPOI的体验,原则就是向前兼容。所以采用.xls的支持。下面就来看看实现步骤
    2021-06-06
  • ItemsControl 数据绑定的两种方式

    ItemsControl 数据绑定的两种方式

    这篇文章主要介绍了ItemsControl 数据绑定的两种方式,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03
  • C#泛型约束的深入理解

    C#泛型约束的深入理解

    本篇文章是对C#中的泛型约束进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C#中@字符d是个什么意思

    C#中@字符d是个什么意思

    这篇文章主要介绍了C#中@字符d是个什么意思?具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • C# 实现简单打印的实例代码

    C# 实现简单打印的实例代码

    C# 实现简单打印的实例代码,需要的朋友可以参考一下
    2013-03-03
  • C# 拼图魔方小游戏

    C# 拼图魔方小游戏

    这篇文章主要介绍了C# 拼图魔方小游戏,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02

最新评论