FreeSql (二十八)事务

FreeSql实现了四种数据库事务的使用方法,脏读等事务相关方法暂时未提供。主要原因系这些方法各大数据库、甚至引擎的事务级别五花八门较难统一。

事务用于处理数据的一致性,处于同一个事务中的操作是一个UnitOfWork,要么全部执行成功,要么全部执行失败。

指定事务对象

FreeSql 提供了指定事务对象的方法,将事务对象暴露给外部;

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

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

同线程事务

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

第一步:扣余额;

第二步:扣库存;

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

//假设已经有了其他wiki页的IFreeSql声明
fsql.Transaction(() => {

    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 事务使用。

系列文章导航

转载于:https://www.cnblogs.com/FreeSql/p/11531423.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值