Spring +mybatis事务处理的疑难杂症
事务处理不起作用
1.配置文件是否对了?
我这里的背景是spring,springmvc。
web.xml
可以看到有两个配置文件,一个配置spring,springmvc.这两个的关系就像父亲跟儿子一样。
service的扫描要放到和配置事务的统一文件下。且springmvc的文件不能二次扫描。不然就不管用咯!
我检查了自己都配置文件ok的。
2.throw异常了吗?
百度里的能人都说spring默认识别RuntimeException,如果你根本全部try-catch了异常,那别说了,快去改吧。要么把try-catch去掉,要么在try{}catch{throw new RuntimeException()},然后再上层取处理(大神说还可以在catch中直接处理,加上“ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();”,反正我是没成功!)。如果要指定某种异常是否回滚,需要如下操作(我没测过):
在@Transaction注解中定义noRollbackFor和RollbackFor指定某种异常是否回滚。
@Transaction(noRollbackFor=RuntimeException.class)@Transaction(RollbackFor=Exception.class)
3.异常真的出去了吗?
谈到这里,心里涌起一阵酸泪。。。天真的我,想要在异常后带数据出去,并且是想带map这样的对象出去,。我立了flag。m默认flase,当有异常就在catch中将它改为true,在finally里面return出去。catch里面执行修改flag和throw new RuntimeException的操作。我测试了,很开心。因为我看到了,异常抛出,也看到了我异常返回携带的数据,心里简直美滋滋,然后去看数据库,并没有rollback。异常抛出了,数据还是插入了。直到我看到我的日志信息里打印“调用XXX方法,正常结束,返回XXX(我的异常信息)”。于是我把finally注释掉了,如释重负。
分析原因:大概是因为方法捕获到了异常,当我在finally执行return时,spring认为我是正常返回,aop就放她回去了。也就不能回滚之前的操作了。
当你看到如"2018-05-23 10:14:19,692 Transaction synchronization rolling back "的信息时,你就是rollback成功,恭喜。
比较笨的我还在担心另一个问题:事务跟并发。如果有心人知道,可以评论区给我解释下,哈哈。
我不能理解的是并发和多线程,比如我现在有一接口,下面有两事务。a事务调用b事务,b事务是独立的。b事务里面有更新,然后查询操作,a事务执行完b事务后,根据b返回的值进行插入操作。当我有多个用户调用时,通过a进入了b。在b里面,更新后,另一个更新。再执行查询。会不会查询到相同的值。
感觉应该不会,当b更新操作完成,还未查询时,b事务未完成,并未提交更新操作到数据库。就好比大家盛饭一样。把碗扔给盛饭的人,盛饭的人打好饭,拿一个走一个。