1、数据库事务
数据库事务是由一组SQL语句组成的,所有的SQL语句执行成功则事务整体成功,任一条SQL语句失败则事务整体失败,数据恢复到事务之前的状态。数据操作的最小单元就是事务,而不是SQL语句!
2、SQL事务操作
1、开启事务(start transaction / begin):事务开始之后,对数据的增删改查操作不会直接修改数据库,而是被记录在日志文件中
2、提交事务(commit):将日志中记录的操作,永久保存到数据库中,并清空日志文件
3、回滚事务(rollback):直接清空日志文件
3、事务四大特性
原子性:事务中的操作要么全部成功,要么全部失败
一致性:事务操作执行前后状态一致
持久性:事务提交之后,数据永久保存到数据库中
隔离性:一个事务的执行不能被其他事务干扰
4、数据库并发访问冲突问题
4.1、脏读:读取到其他事务未提交的数据
4.2、不可重复读:多次读取同一数据,得到的结果不同
4.3、幻读:读取到已经被删除的数据/读取不到新插入的数据
5、MySQL的四种事务隔离级别
读未提交(READ-UNCOMMITTED)
读已提交(READ-COMMITTED)
可重复读(REPEATABLE-READ)MySQL的默认隔离级别
串行化(SERIALIZABLE)
6、分布式事务
在微服务系统中,每个微服务应用都可能会有自己的数据库,它们首先需要控制自己的本地事务。
一项业务操作可能会调用执行多个微服务。如何保证多个服务执行的多个数据库的操作整体成功或整体失败?这就是分布式事务要解决的问题。
7、CAP原则和BASE
CAP原则 C:一致性 A:可用性 P:分区容错性
在分布式事务中
如果保证CP,就意味着要让所有子系统的数据操作要么全部成功,要么全部失败,不允许有不一致的情况发生。但是强一致性会造成性能下降。
如果保证AP,就意味着可以牺牲一定的一致性,允许在各个子系统中存在有的数据操作成功,有的数据操作失败的情况,只要通过后续处理,能够达到最终一致即可。
BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个单词的简写
8、分布式事务方案
XA、TCC、Seata框架AT事务、SAGA、可靠消息最终一致性、最大努力通知等。
8.1、Seata 的 AT 模式(Automatic Transaction)是一种无侵入的分布式事务解决方案。
Seata AT 事务分两个阶段来管理全局事务:
第一阶段: 执行各分支事务
TC事务协调器:协调各个服务的运行状态
TM事务管理器:
RM资源管理器:
XID全局事务ID:
微服务系统中,各服务之间无法相互感知事务是否执行成功,这时就需要一个专门的服务,来协调各个服务的运行状态。这个服务称为 TC(Transaction Coordinator),事务协调器。
订单系统开始执行保存订单之前,首先启动TM,由TM向TC申请开启一个全局事务,这时TC会产生一个全局事务ID(XID),并传回给TM,这样子就开启了全局事务。
全局事务开启后,开始执行创建订单的业务。首先执行保存订单,这时会先启动一个 RM(Resource Manager,资源管理器),并将 XID 传递给 RM。
RM 负责对分支事务(即微服务的本地事务)进行管理,并与 TC 通信,上报分支事务的执行状态、接收全局事务的提交或回滚指令。RM 首先会使用 XID 向 TC 注册分支事务,将分支事务纳入对应的全局事务管辖。
现在可以执行保存订单的分支事务了。一旦分支事务执行成功,RM 会上报事务状态;TC 收到后,会将该状态信息传递到 TM;到此,保存订单过程结束。下面是调用库存服务,减少商品库存,与订单的执行过程相同。
第二阶段: 控制全局事务最终提交或回滚
TM(全局事务管理器)收集齐了全部分支事务的成功状态,它会进行决策,确定全局事务成功,向 TC 发送全局事务的提交请
然后,TC 会向所有 RM 发送提交操作指令,RM 会完成最终提交操作
总结:TC(事务协调器)统一协调所有的各个服务的运行状态,并将结果汇报给到TM(事务管理器),进行的订单服务,执行的操作,都需要向TC汇报,然后TC统一汇报给TM,TM向TC发起全局事务处理请求,TC会向所有RM(资源管理器)发送请求指令,完成事务操作。
Seata的具体工作机制(以订单为例):
第一阶段:执行分支事务
减少库存操作:在执行修改操作之前,先取出旧数据,然后修改库存,将更新后的库存数据取出,和旧数据合并,保存到一个事务回滚日志表:undo_log表,至此,第一阶段分支事务完成,将状态上报给TC。
第二阶段:控制全局事务最终回滚
假如全局事务失败,那么第一阶段已提交的分支事务就要进行回滚操作
首先会收到TC的全局事务回滚指令,根据事务回滚日志表(undo_log表)的记录,将数据恢复为旧的库存数据,然后删除事务日志,完成第二阶段的回滚操作。
第二阶段:控制全局事务最终提交
首先收到TC的全局事务提交指令,接着删除事务日志,就完成了第二阶段提交操作。
详细博客讲解:
https://blog.csdn.net/weixin_38305440/article/details/107583229
8.2、TCC
TCC 与 Seata AT 事务一样都是两阶段事务,它与 AT 事务的主要区别为:
TCC 对业务代码侵入严重:每个阶段的数据操作都要自己进行编码来实现,事务框架无法自动处理。
TCC 效率更高:不必对数据加全局锁,允许多个事务同时操作数据。
以金额扣减为例
第一阶段Try(预留业务资源/冻结):
假如用户购买100元商品,要扣减100元,TCC事务首先对这100元的扣减金额进行预留,或者说冻结这100元。
第二阶段 Confirm(业务提交):
如果第一阶段能够顺利完成,那么说明“扣减金额”业务(分支事务)最终肯定是可以成功的。当全局事务提交时, TC会控制当前分支事务进行提交,如果提交失败,TC 会反复尝试,直到提交成功为止。
当全局事务提交时,就可以使用冻结的金额来最终实现业务数据操作:
第二阶段 Cancel(业务回滚):
如果全局事务回滚,就把冻结的金额进行解冻,恢复到以前的状态,TC 会控制当前分支事务回滚,如果回滚失败,TC 会反复尝试,直到回滚完成为止。