说明
前一篇文字《spring事务之注解形式(一)》发现只是测试了情况,并且异常时属于RunTimeException的,所以造成我以为加了这个“@Transactional(readOnly = false, propagation = Propagation.REQUIRED”,就以为所有的都会回滚,但是我们得代码里面不一样,代码里面是自定义了异常,并且这个异常集成Exception的,所以经过测试,如果是这样是不会回滚的,最后网上搜了看看,并结合实际测试,还是有点理解,所以这篇属于经验之谈,哈哈,最后要弄清源码层次的。
一:抛出Exception异常,情况如下
@Transactional(readOnly = false, propagation = Propagation.REQUIRED,rollbackFor=Exception.class)
public void testException(ParamBean pb) throws Exception {
personInfoSerivice.updateLoginNameException(pb);
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public int updateLoginNameException(ParamBean pb) throws Exception {
Map<String, Object> paramMap = pb.getParamMap();
int i = personInfoMapper.updateLoginName(paramMap);
try{
System.out.println(10/0);
}catch(Exception e){
throw new Exception();
}
return i;
}
1.如果不加rollbackFor=Exception.class,那么此次更新将不会回滚;如果加上则会进行回滚操作。
2.1.如果加rollbackFor=Exception.class,此次更新则会进行回滚操作。
@Transactional(readOnly = false, propagation = Propagation.REQUIRED,rollbackFor=Exception.class)
public void testExceptionForTwo(ParamMap pb) throws Exception {
System.out.println("---------------------");
personInfoSerivice.updatePerson(pb);
personInfoSerivice.updateLoginNameException(pb);
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED,rollbackFor=Exception.class)
public int updateLoginNameException(ParamMap pb) throws Exception {
Map<String, Object> paramMap = pb.getParanMap();
int i = personInfoMapper.updateLoginName(headMap);
try{
System.out.println(10/0);
}catch(Exception e){
e.printStackTrace();
throw new Exception();
}
return i;
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW,,rollbackFor=Exception.class)
public int updatePerson(EngineBean pb) {
Map<String, Object> headMap = pb.getHeadMap();
headMap.put("mobile", "86"+headMap.get("mobileNo"));
int i = personInfoMapper.updatePerson(headMap);
return i;
}
1.1如上代码结果:
如果两个都是一个是REQUIRES_NEW,updatePerson会执行成功,但是updateLoginNameException会进行回滚操作;
分析:因为updatePerson中没有异常抛出,并且是一个新的事物,所以在updateLoginNameException中抛出异常也不会影响到updatePerson的回滚。所以如果updateLoginNameException中try...catch没有抛出异常,则其也会执行成功。
1.2对于上述代码其存在的情况:
1:判断是否是同一个事物;
2:判断是否有try...catch异常,try完有没有抛出异常;如果捕获了异常,但是没有抛出异常,相当于该方法中没有异常;如果捕获到了异常,但是抛出了异常,那么就需要进行异常回滚。
二:抛出RunTimeException默认会回滚
比如之前抛出的10/0的异常:
java.lang.ArithmeticException: / by zero属于运行时异常
对之前的一篇文章中<a href="//www.greatytc.com/p/a4137cf46e65">spring事务之注解形式(一)</a>,抛出的都是运行时异常,对于运行时异常,加了事物注解,spring会默认进行回滚操作.spring文档中有说明如下:
看RunTimeException那段意思是:
Spring框架的事务基础架构代码将默认地 只 在抛出运行时和unchecked exceptions时才标识事务回滚。 也就是说,当抛出一个 RuntimeException
或其子类例的实例时。(Errors
也一样 - 默认地 - 标识事务回滚。)从事务方法中抛出的Checked exceptions将不 被标识进行事务回滚。
异常
异常其实分unchecked exceptions和checked exceptions,我们主要关注unchecked的异常,对于unchecked的异常又分"运行时异常"和“非运行时异常”,网上看见了一片文章觉得很赞,<a href="http://blog.csdn.net/hguisu/article/details/6155636">深入理解java异常处理机制</a>;先借鉴下,后面看看自己也总结下自己的理解,哈哈。
NEXT
昨天下班后跟今天早上来公司加班,又专门的来测试了几种情况,主要还是要看上面所说的,是否是同一个事物,有没有进行异常捕获,捕获后有没有抛出都会影响事物的回滚等。之前也是一直都只是会用,使用xml形式的方式,这次使用注解,才有点深入的理解了些,但是还不够,底层的源码部分还是没有理解,现在只是理解了注解形式的配置而已,所以下面还有深入的分析,希望自己能搞定这种源码理解,最后,你会发现,只有自己尝试做过,遇到的东西才会理解的更深刻。
浩语
__
__ _ ____ __| |__ _____ ___
\ \/ \/ / | \ | \\__ \ / _ \
\ /| | / Y \/ __ \( <_> )
\/\_/ |____/|___| (____ /\____/
\/ \/
走在自己的路上,遇到要遇到的人,经历要经历的事,这才是我们需要面对的。