Spring事务不起作用 问题汇总

最近活少,抽时间总结一些前阵子遇到的问题:使用了Spring事务(用@Transactional注解方式实现)后竟然没有正常回滚,这在线上可是很严重的问题,导致产生脏数据。如何排查并解决呢?这里提供三种思路以供参考:

 

本文测试代码场景:模拟给用户送优惠券操作:kafka异步送,接着预减优惠券库存,然后保存送券记录

情况一:Mysql层使用的是MYISAM存储引擎而不是INNODB

犯错率:1星

MYISAM不支持事务,INNODB支持事务处理,Mysql版本从5.5.8开始,默认使用INNODB存储引擎,如果你线上mysql版本高于这个,或者没有显式的设置存储引擎,这个问题一般不会出现。

解决方案:使用Mysql推荐的支持事务处理的INNODB存储引擎

 

情况二:显式的使用try{}catch(){}来捕获了异常

犯错率:4星

即使程序运行中间抛出了RuntimeException,但是被你catch吃掉了,于是程序继续往下执行,事务也就不能回滚了,代码如下:

Spring事务不起作用 问题汇总_第1张图片

解决方案:建议将try catch异常捕获放到最外层,即controller层

 

情况三:调用方法的对象不是aop代理对象

犯错率:5星

Spring事务不起作用 问题汇总_第2张图片

通过this.update()来减库存,this对象不是aop代理的对象,你可以通过ApplicationContextAware接口来获取代理类

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
* 类描述:获取Spring代理类(上下文)
*/
public class ApplicationContextHolder implements ApplicationContextAware {

    private static ApplicationContext apc;

    public static ApplicationContext getApplicationContext() {
        return apc;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.apc = applicationContext;
    }
}

Spring事务不起作用 问题汇总_第3张图片

我自己碰到的就是情况三。希望对你有参考意义!

你可能感兴趣的:(Java,Java编程之路,Spring事务不起作用,问题汇总)