美文网首页.NETdotNET
FreeSql 教程 (二十八)事务

FreeSql 教程 (二十八)事务

作者: 叶先生_34e6 | 来源:发表于2020-03-17 19:26 被阅读0次

    FreeSql 以 MIT 开源协议托管于 github:https://github.com/2881099/FreeSql

    1、外部事务

    在外部开启事务的场景,可使用 WithTransaction 传入事务对象。

    fsql.Update<xxx>()
      .WithTransaction(指定事务)
      .Set(a => a.Clicks + 1)
      .ExecuteAffrows();
    

    ISelect、IInsert、IUpdate、IDelete,都支持 WithTransaction 方法。

    2、同线程事务

    假设用户购买了价值100元的商品:

    第一步:扣余额;

    第二步:扣库存;

    第一步成功了,到了第二步发现库存不足时,事务可以回滚,扣余额的数据将不生效。

    fsql.Transaction(() => 
    {
      //fsql.Ado.TransactionCurrentThread 此属性可得到事务对象
    
      var affrows = fsql.Update<User>().Set(a => a.Wealth - 100)
        .Where(a => a.Wealth >= 100)
        //判断别让用户余额扣成负数
        .ExecuteAffrows();
      if (affrows < 1)
        throw new Exception("用户余额不足");
        //抛出异常,事务退出
    
      affrows = fsql.Update<Goods>()
        .Set(a => a.Stock - 1)
        .Where(a => a.Stock > 0)
        //判断别让用库存扣成负数
        .ExecuteAffrows();
      if (affrows < 1)
        throw new Exception("商品库存不足");
        //抛出异常,回滚事务,事务退出
        //用户余额的扣除将不生效
    
      //程序执行在此处,说明都扣成功了,事务完成并提交
    });
    

    注意与说明:

    1、数据库事务在线程挂载,每个线程只可开启一个事务连接,重复开启会获取线程已开启的事务;

    2、在事务代码过程中,不可使用异步方法,包括FreeSql提供的数据库异步方法,否则线程将会切换事务不生效;

    3、fsql.Transaction 有防止死锁机制,60秒事务未结束的,将会被其他线程强行提交(不是回滚),可能造成不完整的事务,但仔细一想60秒还没完成的事务是什么原因呢?如果嫌60秒太少了可以在重载方法的参数中设置;

    后续我们将介绍仓储模式下的工作单元,和 DbContext 事务使用。更多事务使用方法请点击这里

    系列文章导航

    相关文章

      网友评论

        本文标题:FreeSql 教程 (二十八)事务

        本文链接:https://www.haomeiwen.com/subject/ypjudhtx.html