[NewLife.XCode]事务处理(算准你的每一分钱)
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode。
整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含多年开发经验于其中,代表作有百亿级大数据实时计算项目。
开源地址:https://github.com/NewLifeX/X (求star, 743+)
为什么需要事务
事务,通俗来讲,同时干几件事,要么一起成功,要么一起失败!
一个比较古老的事务处理案例,(在2002年前后比较常见),就是转账:
- A给B转账100元,先在A账户减100元,然后在B账号加100元,如果A减成功而B加失败,那么就会数据不一致
- A给B转账100元,先在B账户加100元,然后在A账号减100元,如果B加成功而A减失败,同样有问题
此时,需要一个事务把两个操作包含起来,伪代码如下:
begin; A-=10; B+=10; commit; exception rollback; end
这里用白话解释了为什么需要事务,至于事务的原理,绝大部分开发者用不到,感兴趣者可以自行搜索学习。
事务用法
1,最老的用法。从实体类元数据开始
UserX.Meta.BeginTrans(); try { //todo UserX.Meta.Commit(); } catch { UserX.Meta.Rollback(); throw; }
2,基于连接的用法。实体类事务实质上是在连接上开事务,因此同一个连接的多个实体类,不管用哪一个开事务效果都是一样的
var dal = UserX.Meta.Session.Dal; dal.BeginTransaction(); try { //todo dal.Commit(); } catch { dal.Rollback(); throw; }
3,最先进的用法。未提交而离开作用域时执行回滚,还支持多个不同数据库同时打开事务
using (var tran1 = UserX.Meta.CreateTrans()) using (var tran2 = Role.Meta.CreateTrans()) { //todo tran1.Commit(); tran2.Commit(); }
在业务代码里面,如果有问题直接抛出异常或者return跳出作用域即可
事务对自增的影响
在向带有自增的表插入数据时,如果因事务失败而导致回滚,则已“占用”的自增序数不会归还,导致数据库数据的自增数看起来有“断层”的感觉。
系列教程
NewLife.XCode教程系列[2019版]
- 。快速展现用法,代码配置连接字符串
- 。建立表格字段和索引,名字以及数据类型规范,推荐字段(时间,用户,IP)
- 。数据类业务类,泛型基类,接口
- 。连接字符串,调试开关,SQL日志,慢日志,参数化,执行超时。代码与配置文件设置,连接字符串局部设置
- 。自动建立数据库数据表
- 。InitData写入初始化数据
- 。重载拦截,自增字段,Valid验证,实体模型(时间,用户,IP)
- 。如何产生,怎么利用
- 。高并发统计
- 。单表和多表,不同连接,多种写法
- 。多表关联,Map映射
- 。复杂条件,分页,自定义扩展FieldItem,查总记录数,查汇总统计
- 。Sql缓存,更新机制
- 。全表整理缓存,更新机制
- 。字典缓存,适用用户等数据较多场景。
- 。字段精炼,索引完备,合理查询,充分利用缓存
- 。元数据,通用处理程序
- 。Membership
- 。Xml,Json,二进制,网络或文件
- 。常见拆分逻辑
- 。聚合统计,分组统计
- 。批量插入,批量Upsert,异步保存
- 。写入级缓存,提升性能。
- 。备份数据,恢复数据,同步数据
- 。提供RPC接口服务,远程执行查询,例如SQLite网络版
- 。ETL抽取,调度计算处理,结果持久化