Spring的事务传播机制:7种
-
REQUIRED(默认)
-
如果当前没有事务,就新建一个事务,如果已经有事务,就加入到这个事务
-
SUPPORTS
-
支持当前事务,如果当前没有事务,就以非事务方式执行
-
MANDATORY
-
使用当前的事务,如果当前没有事务,就抛出异常(父方法必须有事务)
-
REQUIRES_NEW
-
新建事务,如果当前存在事务,就挂起当前事务。
-
独立提交事务,不受调用者事务影响,父级异常,也正常提交
-
NOT_SUPPORTED
-
已非事务方式执行,如果当前存在事务,则把当前事务挂起
-
NEVER
-
以非事务方式执行,如果当前存在事务,就抛出异常(父方法必须无事务)
-
**NESTED
** -
如果当前存在事务,它将成为父级事务的一个子事务,方法结束并没有提交,等到父事务结束才提交
-
如果当前没有事务,则新建事务
-
如果它异常,父级可捕获异常不会滚,正常提交
-
如果父级异常,它必然回滚(与REQUIRES_NEW的区别****)****
事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败.
脏读:一个事物正在访问数据,并且对数据进行了修改,此时还没有提交,这时另一个事务访问了该数据,然后使用了这个数据。
**不可重复读:重点在修改。**一个事物之内,多次读取统一数据。一个事务没有结束的时候,另一个事务也在访问改数据,在第一个事务两次读取数据之间,由于第二个事务的修改,两次读取到的数据不一致。
**幻读:重点在新增或者删除。**事务不是独立执行时发生的,比如第一个事务访问了范围内数据,同时,第二个事务对这个表中的数据进行了插入操作,第一个事务就会发现前后读取的数据不一致,就好像发生了幻觉一样。
数据库事务的四种隔离级别:
写读是脏读,读写读是不可重复读,whereinsertwhere是幻读
-
读未提交(Read UnCommitted)
-
可以读到未提交的内容
-
在这个级别下,查询是不会加锁的,可能会产生 脏读,不可重复读,幻读
-
读已提交(Read Committed)最常用(SQL Server、Oracle)
-
只能读到已经提交的内容
-
可防止脏读
-
可重复度(Repeated Read)Mysql的默认隔离级别
-
针对“不可重复读”设置的隔离级别
-
当前事务中如果不发生修改,那么事务前后读取到的数据是一样的,且不会读取到其他事务未提交或者已提交的数据。读事务禁止写事务,写事务禁止读和写事务。
-
可防止脏读和不可重复读
-
串行化(Serializeble)
-
数据库最高的隔离级别,事务只能串行化顺序执行,一个一个排队执行
-
脏读,不可重复读,幻读都可以避免,但是执行效率奇差,性能开销大
数据库事务的四大特性:
-
A (Atomic): 原子性,构成事务的所有操作,要么都执行完成,要么全部不执行,不可能出现部分成功部分失败的情况。
-
C(consistency): 一致性,事务开始前和结束后,数据库的完整性约束没有被破 坏。比如A向B转账,不可能A扣了钱B却没有收到。
-
I(Isolation):隔离性,隔离性指不同的事务之间相互不干扰。
-
D(Durability):事务完成后,对数据的修改将会持久化到数据库中。
分布式事务:分布式环境下不同服务之间通过网络协助完成事务称为分布式事务
分布式事务产生场景:
- 微服务架构,跨JVM进程产生分布式事务
- 单体系统访问多个数据库实例,跨数据库实产生分布式事务
- 多服务访问同一个数据库实例
CAP理论:
所有分布式场景中不会同时具备CAP三个特性,因为在具备了P的前提下,C和A是不能共存的。
- C(Consistency)一致性
- A(Availability)可用性
- P(Partition tolerance)分区容错性,分布式系统具备的基本能力。
BASE理论:对CAP理论的延伸
-
Basically Available(基本可用),系统出现故障时,允许损失部分可用功能,保证核心功能可用
-
Soft State(软状态),允许系统中的数据存在中间状态(软状态),允许系统数据同步存在延迟
-
Eventually Consistency(最终一致性),经过一段时间后,所有节点的数据都能达到一致
分布式事务解决方案
- 2PC
- TCC
- 可靠消息最终一致性
- 最大努力通知
1.2PC:
-
准备阶段(Prepare phase) 事务管理器给每个参与者发送Prepare消息,每个事务参与者在本地执行事务,并写本地的Redo/Undo日志,此时事务并没有提交
-
提交阶段(Commit phase) 事务管理器收到了参与者执行失败或者超时的消息时,直接给每个参与者发送回滚消息,否则发送提交消息。事务参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理中使用的锁资源。注意,必须在最后阶段释放锁资源。
-
****基于数据库的XA协议来实现2PC,****数据库提供2PC接口协议,Oracle,Mysql都支持两阶段提交协议。涉及到三个角色,AP、 RM、TM,即应用程序、资源管理器、事务管理器
-
需要本地数据库支持XA协议
-
资源锁需要等到两个结束才释放,性能较差
-
****Seata方案,阿里的开源的分布式解决方案,****seata把全局事务理解成了包含若干分支事务的全局事务,工作在应用层,通过协调本地数据库的分支事务来完成全局事务。性能较好,对业务0侵入。
-
TC(Transaction Coordinator)事务协调器,独立的中间件,需要独立运行,维护全局事务的运行状态。接收TM的的指令发起全局事务的提交和回滚负责与RM通信协调各个分支事务的提交和回滚。
-
TM(Transaction Manager)事务管理器,TM需要嵌入到程序中(Jar包),负责开启一个全局事务,并向TC发起全局提交或全局回滚的指令。
-
RM(Resource Manager),控制分支事务,接收TC的指令,驱动本地事务的提交或回滚。
2. TCC(Try Confirm Cancel)
-
Try 预处理,资源预留。Try执成功,执行Confirm。Try执行失败,执行Cancel。
-
Confirm 确认提交
-
Cancel 需要回滚的状态下,执行分支事务的业务取消。
-
基于Hmily的TCC解决方案(轻量级)利用AOP对本地方法进行拦截处理,并记录日志。只需要暴露Try接口
-
需要注意三种异常;
-
没有调用Try,就调用的Cancel回滚 解决方案:插入执行记录
-
幂等 解决方案:插入执行记录
-
悬挂 Cancel比Try先执行 解决方案:执行一阶段时判断二阶段是否已经执行
3.可靠消息最终一致性:
事务发起方执行完本地事务后发送一条消息,事务参与方一定能够接受消息并处理事务成功。
需解决这几个问题:
- 本地事务和消息发送的原子性(可通过MQ的事务消息解决)
- 事务接收方接收消息的可靠性,接收不到可重复接受
- 消息重复消费(幂等性)
-
本地消息表方案,定时扫描消息表,发送给MQ
-
基于RocketMQ
-
支持事务消息
4.最大努力通知:
-
有一定的消息重复通知机制。
-
接收通知方没有接受到通知,要有一定的机制对消息重复通知
-
消息校对机制。
-
如果尽最大努力也没有通知到接收方,或者接收方想要再次消费消息,可由接收方通过通知放主动查询消息来满足需求
最大努力通知和可靠消息最终一致性的区别:
-
解决方案思想不同:
-
可靠消息最终一致性,消息发起方要保证将消息发出去,并且发送到消息接收方,消息的可靠性有发起方保证(比如事务消息)
-
最大努力通知,消息发起方将业务结果尽最大努力通知给消息接收方,但是如果接收方接收不到,此时需要接收方主动调用发起方的业务查询接口,通知的可靠性由接收方保证
-
业务场景不同
-
可靠消息最终一致性关注的是交易过程的一致性,以异步的方式完成交易。
-
最大努力通知关注的是交易后的事务结果,将结果可靠的通知出去
-
技术解决方向不同
-
可靠消息最终一致性要解决消息从发出到接收的一致性
-
最大努力通知只提供消息接收的可靠性