目录
<a href="http://79100812.blog.51cto.com/2689556/841431#t1">一、事务的定义</a>
<a href="http://79100812.blog.51cto.com/2689556/841431#t2">二、事务管理器</a>
<a href="http://79100812.blog.51cto.com/2689556/841431#t3">三、在ADO.NET中实现事务</a>
<a href="http://79100812.blog.51cto.com/2689556/841452#t4">四、隐式事务 TransactionScope</a>
<a href="http://79100812.blog.51cto.com/2689556/841452#t5">五、在WCF中实现事务</a>
<a href="http://79100812.blog.51cto.com/2689556/841475#t6">六、嵌套式事务</a>
<a href="http://79100812.blog.51cto.com/2689556/841475#t7">七、异步事务</a>
<a></a>
六、嵌套式事务
嵌套式事务经常会出现在项目中,但往往容易被大家忽略,下面介绍一下 嵌套式事务的用法:
一 般项目中,大家都只会把事务用在DAL层,用于管理数据的CRUD,但其实在一些操作中,某些数据的操作必须具有一致性。比如在订单管理中,当插入一条 OrderItem时,Order表内的总体价格,商品数量等也会随之改变。很多人把两个表的操作合成一个方法,放在OrderDAL中完成。但其实这样 做违返设计的原则,因为计算Order的总体价格时可能会包含商品优惠、客户等级、客户积分等等业务逻辑,而在DAL层不应该包含任何的业务逻辑存在的, 所以这样操作应该放在业务层完成。这时候,业务层的方法内就需要同时调用OrderItemDAL的AddOrderItem(OrderItem) 方法和OrderDAL的UpdateOrder(Order)方法,为了保证数据的一致性更新,就需要使用嵌套式事务。但这往往容易被开发人员所忽略, 当Order表的更新成功而OrderItem表的插入失败时,系统不能保证数据的同步回滚,那就会造成数据的逻辑性错误。
下面的例子就是为了保证数据一致性更新而使用的嵌套式事务,在使用嵌套式事务的时候要应该注意及其把对象释放,避免做成死锁。
<a href="http://79100812.blog.51cto.com/2689556/841475#t0">回到目录</a>
七、异步事务
记得在第二节的时候曾经提起过事务类Transaction的方法中包含方法
public DependentTransaction DependentClone(DependentCloneOption)
此方法作用是克隆当前的事务,它在多线程调用同一事务的情况下使用经常使用。其中DependentCloneOption包含有两个选项:
一为BlockCommitUntilComplete,这表示在依赖事务未完成前,事务将处于阻塞状态,只有在所有依赖事务完成后,事务才能执行提交;
二为RollbackInNotComplete,这表示依赖事务必须在事务完成前调用Complete(),否则事务会被视为失败。
在 普通情况下,事务都会通过Transaction.Current 来获取,但此方法只能获取当前线程下的事务对象,在异步方法当中,这只会返回一个空值 null 。此时就需要使用DependentClone 方法获取依赖事务对象 DependentTransaction ,再把此对象作为参数传递到回调函数中。
首 先在主线程中利用 Transaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete) 方法生成一个依赖事务,注意方法使用了BlockCommitUntilComplete的方式生成,即事务将在所有依赖事务使用Complete()后 才能执行提交。
然后利用ThreadPool.QueueUserWorkItem(WaitCallback,Object)方法把依赖事务作为回调参数传递到回调函数中。
最后在回调函数中使用TransactionScope(transaction)构造函数生成对象,这代表把参数transaction作为当前的环境事务对象。观察下面的运行结果,两个线程中的事务都是同一个事务。
<a target="_blank" href="http://blog.51cto.com/attachment/201204/231545679.jpg"></a>
结束语
事务是在多个层次都会使用到的,但很多项目当中往往会忽略了这一点而只在数据层使用,在大型的系统当中这样可能会影响到系统的一致性。特别是在分布式系统当中,操作往往同时存在于多个不同的系统当中,事务的处理更显示出其重要性。
版权声明:原创作品,如需转载,请注明出处。否则将追究法律责任
本文转自 leslies2 51CTO博客,原文链接:http://blog.51cto.com/79100812/841475