你是否真正了解TransactionScope?
相关文章
将不确定变为确定~transactionscope何时提升为分布式事务
将不确定变为确定~transactionscope何时提升为分布式事务~续
将不确定变为确定~transactionscope何时提升为分布式事务~再续(避免引起不必要的MSDTC)
一 了解事务选项,用它来控制嵌套事务
public enum TransactionScopeOption { //如果存在环境事务(我认为应该叫嵌套事务,氛围事务,ambient transaction),那么就加入其中,
如果不存在就创建新事务。如果加入事务那么只有在环境事务提交后才算提交。 Required = 0, //这个事务范围将创建自己的事务,不会加入到当前外部事务中 RequiresNew=1, // 如果处于当前活动事务范围内,那么这个事务范围既不会加入氛围事务 (ambient transaction),也不会创建自己的事务。
当部分代码需要留在事务外部时,可以使用该选项。 Suppress = 2, }
二 何时会提升为分布式事务(何时发起MSDTC请求)
当你的WEB服务器与数据库服务器在同台电脑上,对同一个库进行操作时,它不会提升为分布式事务
当你的WEB服务器与数据库服务器在同台电脑上,对于同一个库,建立多个数据上下文时,它不会提升为分布式事务
当你的WEB服务器与数据库服务器在同台电脑上,当你操作两个库的表,这时才会提升为分布式事
当你的WEB服务器与数据库服务器不在同台电脑上,如果建立多于一个Connection连接,将会发起MSDTC
三 反映到linq to sql中,对于一个数据上下文,由于我们操作不当,也会产生多个Connection连接
这个方法本身没有问题,做一件事件,而且职责很明确,当完成事情后,通过base.SubmitChange()方法提交到数据库,这时,建立了connection,发送了sql语句,完成了这个通讯。
但有时,这种DAL层的动作需要被BLL层的业务进行组合,BLL层可以在一个事务范围内调用多个类似的DAL方法,这时它们会把这种方法当成是分别独立的工作单元,这是我们不希望看到的,因为在我们理解中,一个BLL业务应该是一个工作单元才对,返回到代码中应该是,多个DAL层的方法被解释为SQL语句后,提交一次就OK,所以,上面的代码在进行组合后,可能会产生一些坏味道!
解决方法:
向BLL层开放数据上下文的SubmitChanges()方法及是否提交的属性IsSubmitChange,在BLL层统一做提交,而对于DAL层的独立的方法,在进行submitChanges()时,需要进行判断IsSubmitChange是否为true,如果是,然后再提交,当然这个IsSubmitChange默认为true,即每次调用单独的方法都会完成这个提交,这是正常的,也符合操作的完整性,
而在BLL进行组合方法时,先将必IsSubmitChange设为false,这时,DAL的方法将不会被提交,等待BLL的Submitchange()。
核心代码:
提交属性IsSubmitChange属性默认为true
而对于BLL层,我们公开一个统一的操作对象,它会覆盖掉基类的SubmitChanges方法,它的方法修饰符为public,对BLL层公开。
BLL层的基类BLLBase,可以通过架造方法为IsSutmitChange属性赋值
OK,到这里,我们的BLL无论是调用BLL其它业务组合,还是调用DAL层方法组合,都可以控制代码何时去提交到数据库了,对于一个业务对象,就应该是一个工作单元,呵呵。
本文转自博客园张占岭(仓储大叔)的博客,原文链接:基础才是重中之重~你是否真正了解TransactionScope?,如需转载请自行联系原博主。