1、外部事务
在外部开启事务的场景,可使用 WithTransaction 传入事务对象。
await fsql.Update<xxx>()
.WithTransaction(指定事务)
.Set(a => a.Clicks + 1)
.ExecuteAffrowsAsync();
ISelect、IInsert、IUpdate、IDelete,都支持 WithTransaction 方法。
2、同线程事务
同线程事务,由 fsql.Transaction 管理事务提交回滚(缺点:不支持异步),比较适合 WinForm/WPF UI 主线程使用事务的场景。
用户购买了价值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 >= 1).ExecuteAffrows(); //判断别让用库存扣成负数
if (affrows < 1) throw new Exception("商品库存不足"); //抛出异常,回滚事务,事务退出
});
同线程事务使用简单,需要注意的限制:
事务对象在线程挂载,每个线程只可开启一个事务连接,嵌套使用的是同一个事务;
事务体内代码不可以切换线程,因此不可使用任何异步方法,包括FreeSql提供的数据库异步方法(可以使用任何 Curd 同步方法);