事务相关知识点
2024-11-18 17:17:53 0 举报
AI智能生成
Java事务相关知识点
作者其他创作
大纲/内容
编程式事务
声明式事务
Spring事务
在代码中手动管理事务
类
方法
接口
作用域
当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性信息。
当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息。
不推荐,一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,会导致@Transactional注解失效
readOnly
rollbackFor
rollbackForClassName
noRollbackFor
noRollbackForClassName
DEFAULT
READ_UNCOMMITTED
READ_COMMITTED
REPEATABLE_READ
SERIALIZABLE
分支主题
读未提交
脏读
读已提交
不可重复读
可重复读
幻读
扩展知识
isolation
使用底层数据库默认的隔离级别
读未提交(脏读、 不可重复读) 基本不用
读已提交(不可重复读、幻读)
可重复读(会出现幻读)
串行化
timeout
REQUIRED
REQUIRES_NEW
SUPPORTS
NOT_SUPPORTED
MANDATORY
NEVER
NESTED
propagation
如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务
如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行
如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常
重新创建一个新的事务,如果当前存在事务,暂停当前的事务
以非事务的方式运行,如果当前存在事务,暂停当前的事务
以非事务的方式运行,如果当前存在事务,则抛出异常
表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行
属性
指定事务是否为只读事务,默认值为 false
默认青色背景异常回滚、红色不回滚
指定事务回滚的异常类型,可以指定多个
指定能够触发事务回滚的异常类型名称
设置不需要进行回滚的异常类
设置不需要进行回滚的异常类名称
事务的超时秒数
rollbackFor默认是error和RuntimeException会触发回滚;如果事务中抛出了未捕获的异常,且该异常不是Spring事务管理回滚的异常,则事务可能不会回滚。
未捕获的异常
在事务方法中捕获了异常,但没有重新抛出或没有使用@Transactional注解的rollbackFor属性指定该异常需要回滚,那么事务将不会回滚。
捕获异常后未重新抛出
@Transactional注解只能应用于public方法。如果将其应用于protected、private或包可见性的方法上,虽然不会报错,但事务将不会生效。
非 public 方法
在同一个类中,一个事务方法调用另一个事务方法时(即自调用),由于Spring的事务管理是通过代理实现的,自调用会绕过代理对象,导致事务注解失效。
同一个类中方法调用
例如,将@Transactional注解放在了错误的位置(如类定义上而不是方法上),或者注解的属性配置不正确(如rollbackFor、noRollbackFor、propagation 等),都可能导致事务失效
事务注解使用不当
在Spring的父子容器环境中,如果子容器中的事务方法调用了父容器中的非事务方法,或者父容器中的事务方法调用了子容器中的非事务方法,可能会导致事务失效。
父子容器事务冲突
如果AOP切面捕获了事务方法中的异常,并且没有正确地将异常传播给事务管理器,那么事务可能无法回滚。
切面异常捕获
@Transactiona是基于AOP切面的,如果类没有被事务管理,则事务不生效
类没有被 Spring 管理
在事务执行过程中,如果数据库连接突然断开,事务将无法继续执行,从而导致事务失效。
数据库连接断开
方法被定义成了final的,这样会导致spring aop生成的代理对象不能复写该方法,而让事务失效。
方法被定义为final
失效场景
UnexpectedRollbackException
事务嵌套异常
当内层事务抛出异常并标记为回滚时,外层事务在捕获异常后继续执行并正常结束(就是内层报错,被外层try catch不了了之了)
使用@Transaction注解
准备阶段
事务提交
事务回滚
提交阶段
执行过程中,所有参与节点都是事务阻塞性的,当参与者占有公共资源时,其他第三方节点访问公共资源就不得不处于阻塞状态,为了数据的一致性而牺牲了可用性,对性能影响较大,不适合高并发高性能场景
性能问题
2PC非常依赖协调者,当协调者发生故障时,尤其是第二阶段,那么所有的参与者就会都处于锁定事务资源的状态中,而无法继续完成事务操作(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)
可靠性问题
在阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象。
数据一致性问题
协调者在发出 commit 消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了,那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。
二阶段无法解决的问题
不足之处
两阶段提交,将事务的提交过程分为资源准备和资源提交两个阶段
2PC
CanCommit 准备阶段
执行事务
中断事务
PreCommit 阶段
提交事务
doCommit阶段
三阶段提交协议,是二阶段提交协议的改进版本
与2PC相比,3PC降低了阻塞范围,并且在等待超时后,协调者或参与者会中断事务,避免了协调者单点问题,阶段三中协调者出现问题时,参与者会继续提交事务。
数据不一致问题依然存在,当在参与者收到 preCommit 请求后等待 doCommit 指令时,此时如果协调者请求中断事务,而协调者因为网络问题无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。
优缺点
3PC
Try
第一阶段
业务系统做检测并预留资源 (加锁,锁住资源)
Confirm
Cancle
第二阶段
执行真正的业务(执行业务,释放锁)
是对Try阶段预留资源的释放(出问题,释放锁)
TCC(Try Confirm Cancel)是应用层的两阶段提交
资源预留与隔离,在Try阶段,TCC通过预留必要的业务资源并与其他操作隔离,确保了这些资源在后续阶段中能够被正确地使用或释放。这避免了资源冲突和数据不一致的问题。
幂等性保证,Confirm和Cancel阶段的操作都需要满足幂等性。这意味着无论这些阶段被执行多少次,只要参数相同,结果都应该相同。这确保了即使在网络故障、超时重试或并发请求的情况下,数据的一致性也不会被破坏。
事务回滚与补偿,如果Try阶段失败或事务被取消,TCC通过Cancel阶段来撤销预留的业务资源并释放它们。这实现了事务的回滚和补偿操作,确保了数据能够恢复到一致的状态。
全局事务管理,TCC方案通常包含一个全局事务管理器来管理和控制整个事务活动。它会记录并维护全局事务的事务状态和每个参与方的分支事务状态。当所有分支事务的Try阶段都执行成功时,全局事务管理器会自动调用每个分支事务的Confirm阶段操作来完成分布式事务;而当某些分支事务执行失败时,它会调用分支事务的Cancel操作来回滚分布式事务。
TCC如何保证最终一致性
TCC
① 事务发起方的主业务逻辑请求 OSO 服务开启订单事务
② OSO 向库存服务请求扣减库存,库存服务回复处理结果。
③ OSO 向订单服务请求创建订单,订单服务回复创建结果。
④ OSO 向支付服务请求支付,支付服务回复处理结果。
⑤ 主业务逻辑接收并处理 OSO 事务处理结果回复。
流程
服务之间关系简单,避免服务间循环依赖,因为 Saga 协调器会调用 Saga 参与者,但参与者不会调用协调器。
程序开发简单,只需要执行命令/回复(其实回复消息也是一种事件消息),降低参与者的复杂性。
易维护扩展,在添加新步骤时,事务复杂性保持线性,回滚更容易管理,更容易实施和测试。
优点
中央协调器处理逻辑容易变得庞大复杂,导致难以维护。
存在协调器单点故障风险。
缺点
命令协调
① 事务发起方的主业务逻辑发布开始订单事件。
② 库存服务监听开始订单事件,扣减库存,并发布库存已扣减事件。
③ 订单服务监听库存已扣减事件,创建订单,并发布订单已创建事件。
④ 支付服务监听订单已创建事件,进行支付,并发布订单已支付事件。
⑤ 主业务逻辑监听订单已支付事件并处理。
避免中央协调器单点故障风险。
当涉及的步骤较少服务开发简单,容易实现。
服务之间存在循环依赖的风险。
当涉及的步骤较多,服务间关系混乱,难以追踪调测。
事件编排
实现方式
向后恢复
向前恢复
恢复策略
Saga事务
① 事务主动方在同一个本地事务中处理业务和写消息表操作② 事务主动方通过消息中间件,通知事务被动方处理事务消息。消息中间件可以基于 Kafka、RocketMQ 消息队列,事务主动方主动写消息到消息队列,事务消费方消费并处理消息队列中的消息。③ 事务被动方通过消息中间件,通知事务主动方事务已处理的消息。④ 事务主动方接收中间件的消息,更新消息表的状态为已处理。
①从应用设计开发的角度实现了消息数据的可靠性,消息数据的可靠性不依赖于消息中间件,弱化了对 MQ 中间件特性的依赖。
②方案轻量,容易实现。
①与具体的业务场景绑定,耦合性强,不可公用
②消息数据与业务数据同库,占用业务系统资源
③业务系统在使用关系型数据库的情况下,消息服务性能会受到关系型数据库并发性能的局限
本地消息表
MQ事务消息
最大努力通知
分类
事务协调器,是分布式事务的控制者,负责维护全局和分支事务的状态,驱动全局事务的提交或回滚。
Transaction Coordinator(TC)
事务管理器,负责全局事务的提交和回滚等操作,与TC进行协作。
Transaction Manager(TM)
资源管理器,负责管理和控制分支事务所涉及的资源(如数据库)的操作,与TC进行协作。
Resource Manager(RM)
核心组件
一阶段:TM向TC请求开启全局事务,TM调用每个RM分支,每个RM向TC注册自己分支事务,RM开始执行业务SQL,执行完成后,不提交事务并向TC报告事务的状态。二阶段:业务执行完成后,TM向TC表明各个RM分支已经结束,此时TC检查分支事务的状态来决定是回滚还是进行提交事务。AT模式利用全局锁实现事务隔离,没有代码侵入,框架自动完成回滚和提交。但两阶段之间属于软状态,属于最终一致性,且框架的快照功能会影响性能。
AT模式
Try阶段:资源检查和预留资源。例如,在转账事务中,A账户需要扣除100元,此时会将这100元写入一个中间表(如冻结金额表),并标记事务状态为Try。Confirm阶段:如果Try阶段所有分支事务都成功,则执行Confirm中的代码,正常提交事务并删除中间表的记录。Cancel阶段:如果Try阶段有分支事务失败,则执行Cancel中的方法,根据中间表的数据恢复原来的数据。
TCC模式
SAGA模式
XA模式
事务模式
Seata
分布式事务
事务
0 条评论
下一页