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/11531300.html>

*
(二)自动迁移实体 <https://www.cnblogs.com/FreeSql/p/11531301.html>

*
(三)实体特性 <https://www.cnblogs.com/FreeSql/p/11531302.html>

*
(四)实体特性 Fluent Api <https://www.cnblogs.com/FreeSql/p/11531304.html>

*
(五)插入数据 <https://www.cnblogs.com/FreeSql/p/11531306.html>

*
(六)批量插入数据 <https://www.cnblogs.com/FreeSql/p/11531309.html>

*
(七)插入数据时忽略列 <https://www.cnblogs.com/FreeSql/p/11531316.html>

*
(八)插入数据时指定列 <https://www.cnblogs.com/FreeSql/p/11531318.html>

*
(九)删除数据 <https://www.cnblogs.com/FreeSql/p/11531320.html>

*
(十)更新数据 <https://www.cnblogs.com/FreeSql/p/11531321.html>

*
(十一)更新数据 Where <https://www.cnblogs.com/FreeSql/p/11531324.html>

*
(十二)更新数据时指定列 <https://www.cnblogs.com/FreeSql/p/11531327.html>

*
(十三)更新数据时忽略列 <https://www.cnblogs.com/FreeSql/p/11531334.html>

*
(十四)批量更新数据 <https://www.cnblogs.com/FreeSql/p/11531335.html>

*
(十五)查询数据 <https://www.cnblogs.com/FreeSql/p/11531339.html>

*
(十六)分页查询 <https://www.cnblogs.com/FreeSql/p/11531341.html>

*
(十七)联表查询 <https://www.cnblogs.com/FreeSql/p/11531346.html>

*
(十八)导航属性 <https://www.cnblogs.com/FreeSql/p/11531352.html>

*
(十九)多表查询 <https://www.cnblogs.com/FreeSql/p/11531362.html>

*
(二十)多表查询 WhereCascade <https://www.cnblogs.com/FreeSql/p/11531372.html>

*
(二十一)查询返回数据 <https://www.cnblogs.com/FreeSql/p/11531376.html>

*
(二十二)Dto 映射查询 <https://www.cnblogs.com/FreeSql/p/11531381.html>

*
(二十三)分组、聚合 <https://www.cnblogs.com/FreeSql/p/11531384.html>

*
(二十四)Linq To Sql 语法使用介绍 <https://www.cnblogs.com/FreeSql/p/11531392.html>

*
(二十五)延时加载 <https://www.cnblogs.com/FreeSql/p/11531395.html>

*
(二十六)贪婪加载 Include、IncludeMany、Dto、ToList
<https://www.cnblogs.com/FreeSql/p/11531404.html>

*
(二十七)将已写好的 SQL 语句,与实体类映射进行二次查询
<https://www.cnblogs.com/FreeSql/p/11531416.html>

*
(二十八)事务

*
(二十九)Lambda 表达式 <https://www.cnblogs.com/FreeSql/p/11531425.html>

*
(三十)读写分离 <https://www.cnblogs.com/FreeSql/p/11531430.html>

*
(三十一)分区分表 <https://www.cnblogs.com/FreeSql/p/11531435.html>

*
(三十二)Aop <https://www.cnblogs.com/FreeSql/p/11531471.html>

*
(三十三)CodeFirst 类型映射 <https://www.cnblogs.com/FreeSql/p/11531543.html>

*
(三十四)CodeFirst 迁移说明 <https://www.cnblogs.com/FreeSql/p/11531550.html>

*
(三十五)CodeFirst 自定义特性 <https://www.cnblogs.com/FreeSql/p/11531576.html>