事务失效情况

同类A调B | A无事务 | B有事务    事务失效, 报错AB都不回滚
同类A调B | A有事务 | B无事务    事务包括AB,报错AB都回滚
不同类A调B | A有事务 | B无事务  事务包括AB,报错AB都回滚
不同类A调B | A无事务 | B有事务  事务只包含B,A报错AB都不回滚,B报错A不回滚B回滚


方法A调用方法B:
1、如果只有A加@Transactional注解;则AB在同一事务中;
2、如果只有B加@Transactional注解;AB方法为同一类,事务失效;AB不同类,只有B有事务;


原理:

1.spring AOP、事务都是基于动态代理实现
2.spring在扫描bean时,会走到@Transactional注解,
3.事务工作逻辑是生成一个代理类,通过代理增强原有逻辑。
4.但是这个注解被同一个类中的其他方法调用,那么该方法的调用并没有通过代理类,就导致事务失效了

打个比方CGLIB代理,会有这么一个方法

public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {  
  System.out.println("前置代理");  
  //通过代理类调用父类中的方法  
  Object result = proxy.invokeSuper(obj, args);  
  System.out.println("后置代理");  
  return result;  
}

A调B,B有事务,B本来会因为事务注解生成这个代理类,但是现在不走代理了,所以事务失效了。

Seata分布式事务失效情况及可能原因如下: - **配置无误但全局事务不回滚**:在配置无误且已添加`@GlobalTransactional`注解的情况下,分支事务抛出异常,全局事务却不能回滚。例如在如下代码中,即使分支事务出现异常,全局事务也未回滚: ```java @Override @GlobalTransactional public void tryPayOrderByBalance(PayOrderFormDTO payOrderFormDTO) { // 1.查询支付单 PayOrder po = getById(payOrderFormDTO.getId()); // 2.判断状态 if(!PayStatus.WAIT_BUYER_PAY.equalsValue(po.getStatus())){ // 订单不是未支付,状态异常 throw new BizIllegalException("交易已支付或关闭!"); } // 3.尝试扣减余额 userClient.deductMoney(payOrderFormDTO.getPw(), po.getAmount()); // 4.修改支付单状态 boolean success = markPayOrderSuccess(payOrderFormDTO.getId(), LocalDateTime.now()); if (!success) { throw new BizIllegalException("交易已支付或关闭!"); } // 5.修改订单状态 orderClient.markOrderPaied(po.getBizOrderNo()); } ``` 这种情况可能涉及多种因素,需要进一步排查[^1]。 - **继承`WebMvcConfigurationSupport`**:继承`WebMvcConfigurationSupport`可能会导致Seata分布式事务失效,解决方案是改为实现`WebMvcConfigurer`接口,修改后Seata就能正常处理分布式事务,相关表也可正常回滚[^4]。 - **Fegin调用使用Fallback降级或异常被全局处理**:Fegin调用使用了Fallback降级或者抛出的异常被全局处理,会导致Seata分布式事务不生效,事务无法回滚[^5]。 - **undo_log表及相关表存在脏数据**:undo_log表以及seata持久化数据库的brach_table、global_table、lock_table、undo_log表中的脏数据,可能会影响事务的正常回滚,清除这些脏数据或许能解决问题[^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值