首页 > 代码库 > EF事务嵌套

EF事务嵌套

EF中采用的是数据上下文DbContext,当针对数据库的所有操作共用一个数据上下文的时候,会使用同一个连接对象,因此连接打开一次,最后Save的时候关闭连接,避免了频繁的创建连接对象打开关闭,这在一定程度上提升了性能。

对比传统的DbHelper做法,传统的DbHelper通常将线性单元方法进行了封装,每个方法都会创建一个连接对象、打开关闭,因为DbHelper不能采用一个公用的Connection对象,因为如果共用一个连接对象,那么所有的请求操作都会采用这一个连接对象,打开关闭,如果访问量大的时候,瓶颈可想而知。

DAL层都是封装的原子性操作,但是在业务层中,要调用不同的DAL层对象,同时进行多个原子操作。

EF在这一点做到了采用同一个数据上下文,采用同一个连接对象,采用同一个事务,提升了性能。

但是如果你的DbContext是线程级别的,并且事务方法又互相调用就存在了事务嵌套问题,因为嵌套的事务一旦提交就作废了,所以要保证必须是最后提交,如果嵌套事务异常也要在保证外层的回滚

最后采用了事务计数的思想

  public class MyDbContext : DbContext, ITransaction    {        public MyDbContext(string connectionString)            : base(connectionString)        {            // 是否启动延迟加载            Configuration.LazyLoadingEnabled = false;            // 是否启动代理            Configuration.ProxyCreationEnabled = false;            Configuration.AutoDetectChangesEnabled = false;            Configuration.ValidateOnSaveEnabled = false;        }        public void BeginTransaction()        {            if (this.Database.CurrentTransaction == null)            {                this.Database.BeginTransaction();            }            this.BeginCounter++;            this.IsTransaction = true;        }        public int Commit()        {            this.BeginCounter--;            int result = this.SaveChanges();            if (this.BeginCounter==0)            {                this.IsTransaction = false;                DbContextTransaction transaction = this.Database.CurrentTransaction;                if (transaction != null)                {                    transaction.Commit();                    transaction.Dispose();                    result += 1;                }            }            return result;        }        public void Rollback()        {            this.BeginCounter--;            if (this.BeginCounter == 0)            {                this.IsTransaction = false;                DbContextTransaction transaction = this.Database.CurrentTransaction;                if (transaction != null)                {                    transaction.Rollback();                    transaction.Dispose();                }            }            else            {                //this.BeginCounter = 1;                throw new Exception("嵌套内部事务异常");            }        }        private bool isTransaction = false;        /// <summary>        /// 事务性操作        /// </summary>        public bool IsTransaction        {            get { return isTransaction; }            set { this.isTransaction = value; }        }        private int beginCounter = 0;        /// <summary>        /// 事务计数器        /// </summary>        public int BeginCounter        {            get { return beginCounter; }            set { this.beginCounter = value; }        }    }

 

EF事务嵌套