mirror of
https://github.com/dotnetcore/FreeSql.git
synced 2026-04-04 04:30:56 +08:00
update
1
Home.md
1
Home.md
@@ -47,6 +47,7 @@ FreeSql是一个功能强大的NETStandard库,用于对象关系映射程序(O
|
||||
* [字符串](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e5%ad%97%e7%ac%a6%e4%b8%b2)
|
||||
* [日期/时间](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e6%97%a5%e6%9c%9f)
|
||||
* [其他](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0%e5%85%a8%e8%a7%88)
|
||||
* [事务](https://github.com/2881099/FreeSql/wiki/%e4%ba%8b%e5%8a%a1)
|
||||
* [读写分离](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb)
|
||||
* [性能](https://github.com/2881099/FreeSql/wiki/%e6%80%a7%e8%83%bd)
|
||||
* API参考
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
* [字符串](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e5%ad%97%e7%ac%a6%e4%b8%b2)
|
||||
* [日期/时间](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e6%97%a5%e6%9c%9f)
|
||||
* [其他](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0%e5%85%a8%e8%a7%88)
|
||||
* [事务](https://github.com/2881099/FreeSql/wiki/%e4%ba%8b%e5%8a%a1)
|
||||
* [读写分离](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb)
|
||||
* [性能](https://github.com/2881099/FreeSql/wiki/%e6%80%a7%e8%83%bd)
|
||||
* API参考
|
||||
|
||||
53
事务.md
Normal file
53
事务.md
Normal file
@@ -0,0 +1,53 @@
|
||||
FreeSql现实了简单数据库事务方法,脏读等事务相关方法均未提供。首先不大建议擅自控制事务级别,数据库默认事务已经够用了;再者这些方法各大数据库、甚至引擎的事务级别五花八门很难统一,强制现实只会徒增理解成本,这不是FreeSql的设计原意(最方便的ORM)。
|
||||
|
||||
事务用于处理数据的一致性,事务的定义是处于同一个事务中的操作是一个工作单元,要么全部执行成功,要么全部执行失败。
|
||||
|
||||
假设用户购买了价值100元的商品:
|
||||
|
||||
第一步:扣余额;
|
||||
|
||||
第二步:扣库存;
|
||||
|
||||
第一步成功了,到了第二步发现库存不足时,事务可以回滚,扣余额的数据将不生效。
|
||||
|
||||
```csharp
|
||||
//假设已经有了其他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<Shop>().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秒可在方法参数中设置;
|
||||
|
||||
## 事务为什么不适合异步方法
|
||||
|
||||
事务的操作会占用资源,导致其他地方的读写被阻塞,使用原则应该是尽快关闭。
|
||||
|
||||
然而异步机制是排队的过程,事务体内的异步方法调试任务排队执行,如果此时任务队列很长,事务的关闭时间将会延长,不仅会导致越来越多的读写操作被阻塞,而且它们还占用着任务池资源,在极端条件下这简直是一个死循环。
|
||||
|
||||
> 所以请不要在事务体中执行异步方法
|
||||
|
||||
这样一来,我们就有了一个非常好的借口将事务对象临时存储在线程上,使用时不必层层传递事务对象。
|
||||
Reference in New Issue
Block a user