mysql中,我们可以使用begin开始事务,rollback回滚事务,commit提交事务
redolog 记录变更、undolog回滚
Spring中,使用@Transaction标记事务
原子性(Atomic)
要么全部成功,要么全部失败,没有中间状态
一致性(Consistency)
指的是在执行事务前后,事务外访问数据的时候,数据是一致的,要么看到的是成功的,要么看到的是失败的结果,不会多任务查询到的数据不一样。
隔离性(Isolation)
一个事务在未完成时,另一个事务不会影响到他
持久性(Durability)
会有持久化效果,改变是永久的
随着系统越来越庞大,我们为了提高可用性、维护性、吞吐量等等技术指标,可以采用SOA来改善原有架构,业务计算的问题解决后,数据库便成了整个系统中的瓶颈
分库分表
数据库集群/分布式存储方案在当前最主流的便是采用分库分表方案做多机存储和负载
分库分表能减少单表
在多机存储的环境下,传统的事务机制便无法正常运行了。
表垂直拆分
把表中的列拆分成多个部分,就是把一张很多字段的表,拆分成多个表
- 减少查询时候的网络i/o
- 提高查询效率
表水平拆分
按行拆分,一张表里的行数越多,查询效率越低
水平拆分指定就是把原来的一张表中存放的数据按照固定行数拆分成多个表来存储
- 有效的提高查询效率
分表后依然可以使用本地事务,但是单机负载依然是瓶颈。
分库
分库指的是
- 同样的表结构
- 不同的数据库中
- 每个节点中保存副本数据或分布式存储
- 可以把事务路由到同一库中,则可以保证事务特性,尤其是强一致性
- 当数据分散到数据集群中做跨库查询的时候,无法保证强一致性
微服务下的多库存储
回想CAP定理和BASE理论
base通过允许损失部分可用性来提高数据最终一致性
海量数据/高并发系统分布式事务解决方案
强一致性
强一致性会带来系统大量的损耗,存在单点故障问题,在提交事务阶段会产生阻塞,直到结束才会释放资源。高并发场景下表现并不好。
刚性事物和柔性事物
- 刚性事务:遵循ACID原则,强一致性。
- 柔性事务:遵循BASE理论,最终一致性
分布式事务解决方案
XA两阶段提交方案
数据库实现xa协议,保证事务,mysql oracle等。
一阶段提交
由单数据源数据库实现,以mysql为例,
- 记录redolog
- 数据库通过redolog完成事务
单节点提交简单直观,没有和其他节点的通讯,性能好
二阶段提交
主要由商业数据库实现,但并不常用,强一致性,性能低
- 增加中间角色,事务管理器,来收集各数据库事务状态
- 阻塞
- 事务管理器 是由数据库提供的中间件
接口查询
TCC
在互联网项目,电商系统,app领域占据主力地位
接口需要自己实现或使用第三方开源框架
二阶段提交改进
对代码有侵入
- Try
- confirm
- cancel
有侵入性、需要做幂等操作
二阶段提交协议
二阶段提交协议可以保证数据强一致性
二阶段
- 准备
- 提交
角色:
- 协调者
- 负责收集准备信息(预提交)
- 准备完成,发起正式提交
- 参与者
- 数据库
二阶段提交把事务分为两个阶段,即准备阶段和提交阶段,准备阶段负责收集每个参与者提交数据的预提交信息,其实是收集每个数据节点是否能够成功执行命令,
如果其中某些节点无法执行,那么会反馈给协调者失败信息,然后协调者会发送回滚信息到每个数据节点以保证一致性
如果全部返回准备好的消息,那么协调者会正式向数据节点提交数据变更。
问题
同步执行
每一次收集准备信息都需要等所有数据节点返回信息,造成同步等待。
单点故障
需要考虑数据节点和协调者的单点故障问题
执行提交
数据节点提交变更,无法保证是否真正提交了
二阶段提交存在很多潜在和小概率问题,那么在数据一致性要求高的场景下会造成数据不一致的现象发生,一旦发生数据不一致的情况后,后续人工干预的操作会浪费大量的时间,对银行、余额这类业务,还有可能造成资产流失。
三阶段提交协议
三阶段提交是对二阶段提交的改良版本,增加了预备阶段,解决了同步阻塞问题。
TCC模式
TCC
Try
- 尝试
- 完成所有业务检查
- 隔离预留资源
Confirm
- 真正的执行业务
- 使用try阶段预留的资源
- 幂等
Cancel
- 混滚
主业务
- 发起事务
事务管理器
- 执行tcc操作
- 创建事务ID来记录整个事务链路
- 实现嵌套事务业务逻辑
执行流程
第一阶段
- 主业务调用所有子业务的try操作
- 事务管理器记录操作日志
第二阶段
- 所有try操作成功时,事务管理器执行confirm操作
- 有失败时,执行回滚cancel操作
t -> cc 关系绑定
T是由主业务发起的,CC操作和T操作不在一台机器上
- 通过配置文件
- 通过Spring注解
try阶段进行了锁定资源操作,锁定不成功就认为是不可进行的,锁定成功就最终一定会成功。
框架
tcc-transaction
https://github.com/changmingxie/tcc-transaction
Hmily
https://dromara.org/website/zh-cn/
ByteTCC
https://github.com/liuyangming/ByteTCC
AOP
TCC 通过AOP,面向切面编程来对confirm/cancel操作透明化
幂等
数据库中的唯一索引
分布式锁
状态机
补偿模式
重试
固定次数,固定时间,消息队列,定时任务
下一次访问修复
定时校对/核对 quartz、xxl-job、elastic-job