如下bll方法,在执行时会报事务嵌套异常。bll方法里开启了分布式事务,dal方法里又启动了数据库事务。通过查看异常堆栈,发现异常是在执行BillsDal.Add(bill);方法里的var trans = conn.BeginTransaction();这条语句抛出来的。
持久层框架:dapper, db:mysql。
bll方法:
public static bool AddInterestBill(t_bills bill, t_info_jxdetailed his) { using (var trans = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted })) { BillsDal.Add(bill); his.BillId = bill.BillId; BillsDal.AddInterestHis(his); trans.Complete(); return true; } }
dal方法:
/// <summary> /// 插入记录(启用事务来处理主键BillId) /// </summary> /// <param name="entity"></param> /// <returns></returns> public static bool Add(t_bills entity) { if (entity.CreatedTime == DateTime.MinValue) { entity.CreatedTime = DateTime.Now; } lock (syncRoot) { var conn = _conn; conn.Open(); //_conn.setAutoCommit(false);//设置自动事务提交为false var trans = conn.BeginTransaction(); try { var maxId = conn.ExecuteScalar<long?>("SELECT MAX(BillId) FROM T_Bills;", trans); if (maxId == null || maxId < CommonBase.BillId_DefaultValue) { maxId = CommonBase.BillId_DefaultValue; } entity.BillId = maxId.Value + 1; long i = conn.Insert<long>(entity, trans); trans.Commit(); i = 1; //执行Insert返回值是0,这里给1,以供下面的判断 return i > 0; } catch { trans.Rollback(); throw; } finally { conn.Close(); } } }
异常截图:
其中:分布式事务TransactionScope的定义为:
IDbConnection的BeginTransaction方法定义为: