TransactionScope是.net环境下的事务,可以提升为分布式事务,这些知识早在很久前就已经说过了,今天不再说它,今天主要谈谈Savechanges()这个方法在TransactionScope块里的作用,我们知识TransactionScope只有显示的提交动作而没有回滚,那么它如何实现回滚呢?事实上,.net从来就是一门不啰嗦的语言,它把回滚理解为:“当程序出现问题时,就是回滚的时候”!
提交出现问题的表现?
- 就是throw出来的异常
- 当前你可以不加try…catch块,也会throw出来
- 当你加了try…catch,而又没有throw出来,那你的事务中的回滚就失效了,即数据的一致性没有保正了
所以,如果你要封装自己的savechanges方法,就必须把异常显示的抛出来,像这样的代码是正常的
protected virtual void SaveChanges() { try { Db.SaveChanges(); } catch (DbUpdateConcurrencyException) { throw new DbUpdateConcurrencyException("Lind.DDD框架在更新时引起了乐观并发,后修改的数据不会被保存"); } catch (DbEntityValidationException ex) { List<string> errorMessages = new List<string>(); foreach (DbEntityValidationResult validationResult in ex.EntityValidationErrors) { string entityName = validationResult.Entry.Entity.GetType().Name; foreach (DbValidationError error in validationResult.ValidationErrors) { errorMessages.Add(entityName + "." + error.PropertyName + ": " + error.ErrorMessage); } } throw; } catch (Exception) { throw; } }
而事实上,我们在UI层或者应用层,可以把异常消化,因为你的页面可能不希望看到500的错误,当然你也可以设置全局的500,404,403等错误页!
像这样代码,把异常消化,对事务是没有影响的,事务能否回滚,只与saveChanges()有关!
try { InsertData(); } catch (Exception ex) { Console.WriteLine(ex.Message); }
感谢各位的阅读!
本文转自博客园张占岭(仓储大叔)的博客,原文链接:EF架构~TransactionScope与SaveChanges的关系,如需转载请自行联系原博主。