service中配置的事务回滚不起作用

这两天一直在研究一个东西,关于事务回滚的,因为我突然发现我们项目竟然不支持,不支持,但是我们整个事务的配置文件都是有的。

关于事务配置,我就不再多阐述了,可以参考这篇文章: 事务回滚配置

下面说我遇到的问题吧,就是所有的配置都完成了,但就是不起作用,抛出了RuntimeException就是不会滚,数据库操作该执行还是执行了。最后才想到会不会是数据库表引擎的问题,立马去看,果然,表引擎都是myisam,我的天,把引擎改一下,立马好了。

下面总结一下,在确认配置文件都配置好,所有工作都无误的情况下还是不支持事务时的几个检查方面:

使用@Transactional注解的回滚方式的检查方面

1、看方法是否是public的,注解方式默认只在public修饰的方法上起作用,protected、private 或者 default 修饰的方法上使用@Transactional时不会报错,但是事务设置不起作用。

2、检查是不是同一个类中方法的调用。(比如同一个方法中存在A和B两个方法,A方法去调用B方法)

基于spring aop的配置回滚方式的检查方面

1、配置文件中的aop相关配置,看expression配置的路径是否可以扫描到你的方法。

<aop:config>
        <aop:pointcut id="transactionPointcut" expression="execution(* com.test.service.impl..*.*(..))" />
        <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
</aop:config>

上面代码中我配置的是 扫描com.test.service.impl 包及其子包中的所有的方法。

顺便给出execution表达式常见的相关配置说明:

execution(public * *(..))                      任意的公共方法

execution(* set*(..))                          任何以set开头的方法

execution( * com.test.service.impl.*.*(..))       com.test.service.impl包下的任意方法

execution( * com.test.service.impl..*.*(..))      com.test.service.impl包及其子包下的任意方法

下面是以上两种配置方式都可能出现不回滚的检查方面:

1、数据库引擎要支持事务,如果是MySQL,注意表要使用支持事务的引擎,比如innodb,如果是myisam,事务配置是不起作用的。

2、看service是否进行了try...catch...但是没有在catch块中继续抛出异常。

以下代码进行了try...catch...将异常捕获了,所以spring没法识别你的异常,当然也不会进行回滚。

public void test () { 
    try{
        insert(a);
        delete(b)
    } catch {
        System.out.println("不会回滚!!!");
    }
}

    正解如下,进行了try...catch...之后再catch块中继续进行异常的抛出,这样就可以实现回滚。

public void test () { 
    try{
        insert(a);
        delete(b)
    } catch {       
         throw new RuntimeException("操作失败!!!");
    }
}

好了,到此结束,自己问题也解决了,希望简单的总结能帮到一个两个的同行!

此文为原创,欢迎转载,转载请注明出处,谢谢微笑



猜你喜欢

转载自blog.csdn.net/pavel101/article/details/79640400