System.InvalidOperationException nested transactions are not supported

本文介绍了一个在使用Dapper和MySQL进行数据库操作时遇到的事务嵌套异常问题。该问题出现在同时使用分布式事务TransactionScope和数据库本地事务的情况下,具体表现为在DAL层尝试开始新的事务时引发异常。

如下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方法定义为:

 

转载于:https://www.cnblogs.com/buguge/p/6268726.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值