ssm框架事务回滚问题(艰辛总结)

说一下事情的原委吧,也希望后面遇到类似问题的朋友少走点弯路(希望大家能看一下,对你解决问题思路肯定有帮助)

自己之前是按照视频整合ssm框架,老师在配置好事务之后,并未进行测试,自己也是出于好奇就进行事务回滚测试,自己插入两条记录到数据库,第一条是正确信息,然后第二条是错误的,但是发现当报出异常后数据库信息未发生回滚,自己也是通过各方大佬是各种方法去做测试,依然没有一点效果(搞了一个下午,很崩溃),有时候被bug搞得比较晕的时候最应该做的就是什么也不做,休息一下,然后第二天还是依旧和bug继续做斗争,自己发现自己这些配置应该没错,毕竟大家都是这么配置的测试的都没问题,自己觉得应该换一种思路,是不是之前文件配置出现问题(之前没有想是因为跟老师配置的一样,没去质疑),不得不说idea这个工具确实是强大啊,能帮不少忙,大家看下我的配置要求(spring文件不对controller层进行管理,而springMVC只需要对controller进行管理)说到这里我想大家应该都知道,我的问题在哪里了吧,请看图:

这里是applicationContext.xml文件的注解扫描配置,idea点击左边那个查看就能看到你现在配置情况下能扫描到的类了,这里完全符合我的预期目的。

附上代码:

 <!--开启注解扫描,处理service层和dao层,controller不需要spring去处理-->
    <context:component-scan base-package="snack">
        <!--配置那些注解不扫描-->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

然后再看下spingMVC的配置文件图:

这里很明显它能够扫描到我现在所有类的注解,而我值仅仅需要它扫描studentController这个类(因为之前一直以为include是选择一个报下符合条件的类,其他都排除,而exclude则是除了..在外其他都符合,这里看来include好像跟我理解不一样,稍后我会再去了解)。

标签介绍:https://blog.csdn.net/chlei_/article/details/100576908

代码也附上:

  <!--开启扫描注解,只扫描Controller注解-->
    <context:component-scan base-package="snack">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

最后自己修改成精确到那个包(cotroller):

<!--开启扫描注解,只扫描Controller注解-->
    <context:component-scan base-package="snack.controller">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

总结一下解决此类问题的思路:

先要明确自己配置的文件管理范围没有重复,就是像我这里,最好的方式就是我说的,idea查看你配置后的能扫描到的文件注解范围,当然如果你没用idea,我的另一种方法就是建议你换成idea,再者就是你的注释必须是在service实现层(反正我是,你要是调皮谁你便),然后事务问题再不能回滚那就是事务本身的使用问题了,这就是要明确bug出在哪里,这很重要,后面自己也是把事务的很多别人遇到的bug测试了一遍(一下午也算有点收获,就是这些了)。

下面总结一下:

首先要明确,spring事务默认回滚的就是RuntimeException这个异常类及其子类,我很好奇为什么连Exception也是默认不能回滚的(可能父类不能回滚,说白了就是自己包括自己儿子可以,自己父辈以上不管,有点不孝的嫌疑,但是毕竟是外国人开发的,原谅它),所以你需要它回滚,那么解决方法下面也是有几种:

一、就是不要进行try catch,如下(我已经测试过了,没问题):

二、如果你非要try catch进行处理,那么下面也是有两个解决方案的:

1.因为默认进行抛RuntimeException,那么我们就给他抛这个异常不就好了(这里也测了):
 

try {
            //这里是前端传入的
            studentDao.saveStudent(student);
            //这里是测试异常的,我只输入一个属性,名字属性会报空异常
            Student student1 = new Student();
            student1.setSex("女");
            studentDao.saveStudent(student1);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }

2.手动提交回滚操作(这里会测的):

  @Transactional(rollbackFor = Exception.class)
    public void saveStudent(Student student) {
        try {
            //这里是前端传入的
            studentDao.saveStudent(student);
            //这里是测试异常的,我只输入一个属性,名字属性会报空异常
            Student student1 = new Student();
            student1.setSex("女");
            studentDao.saveStudent(student1);
        } catch (Exception e) {
            e.printStackTrace();
            //手动提交事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

这里提示一下:有很多人因为没有加rollbackFor = Exception.class导致不能回滚,那就是因为默认是RuntimeException,不能进                           行提交事务,你的rollbackFor属性就是定义碰到什么异常给你回滚,这里定义exception,估计绝大部分都没什                             么问题了。

最后希望对需要的人能够有帮助,祝您早日战胜bug....

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值