什么是事务,事务的应用场景
做项目时,经常会遇到一些需求,比如注册用户时,要求同时存入用户的基本信息和初始化该用户的帐户,如果在这两个环节中的任何一个地方出错,则要求回滚所有操作,这就是事务,它的主要目的是为了数据的完整性,即要么全盘成功,要么全盘失败,大家都穿一条裤衩。
今天我要说的复杂事务
事务的概念很简单,应用起来也很方便,当然可以在存储过程中直接实现事务保证数据的完整性,但是我一般不会这样做,因为我基本把数据库就当做一个数据仓库而已,它是一个容器,没有其他逻辑,逻辑都放领域层来处理,因为这不是我们今天的主要话题,所以就不多讲了。回到正题,那么我们要在C#中实现事务是怎么实现的呢,很简单,直接调用Connection的BeginTransaction方法即可,我们拿ADO.Net中的SqlServer举例,完整的应用示例如下:
以上代码两Usr表中插入两条数据,要求这两条数据必须都成功插入,否则回滚,逻辑很简单。
更好的方式
上面的代码没什么问题,但是如果我们每个地方都这样写,那的确很繁琐,所以出来了很多ORM框架来辅助我们,再看一下EntityFramework是怎么实现事务的
代码:
using (RetailEntities context = new RetailEntities()) { context.Customers.Add(entity1); context.Customers.Add(entity2); context.SaveChanges(); }
估计大家都用过,没错,它在SaveChanges方法之前,自动为我们开始了一个事务。这样做的好处,不言而喻,比起上面那样做可谓是简洁了许多。但是今天我们不使用EntityFramework,而是使用自己的方式来解决将要面临的问题。
我实现事务的方式
看过我博客的朋友有可能会知道,我以前也写过一个ORM框架(XDBFramework),今天我们主要不讲这个框架,但会引用其中的代码来说明问题,下面就上代码,来看在XDBFramework中是怎样实现事务的。
DataContext类
DataAccess类,也就是上面的_da
生成的DataContext类
调用代码:
using (var context = new DataContext()) { long count = context.Admin.Count(); var a = DataContextStatic.Recharge.Count(s => s.State == Convert.ToInt32(1)); string passport = "x" + DateTime.Now.Ticks; context.BeginTransaction(); try { context.Admin.Insert(new Model_Admin { Passport = passport, Password = "123456", AddTime = DateTime.Now }); context.Admin.Insert(new Model_Admin { Passport = passport + "_2", Password = "123456", AddTime = DateTime.Now }); context.CommitTransaction(); } catch { context.RollbackTransaction(); } }