spring事务回滚问题
2015-08-26 15:41
519 查看
刚刚接到一个上家公司同事的一个电话,问我为什么service方法事务不会滚了,日志打印了,调用webservice报错。
我让他把这个调用执行webservice的方法截图发给我,如下:
这个方法是一个调用执行webservice的方法,并返回执行结果给调用者,就是上面这个方法报错。我一看到这个代码,中有try catch,我想一定是这个方法中把异常给拦截了,service中捕获不到异常,导致aop拦截不到异常信息,导致事务不回滚。
但是仔细一看发现这个方法虽然捕获了异常,但是捕获后有重新抛出异常。
这不是又抛出异常了吗?应该没有问题了啊。
仔细分一下,就发现问题就出在这里,它抛出的是一个Exception,而spring在事务回滚时,是只对runtimeException或者其子类的异常才会回滚。
而且这里抛出的是一个Exception,别人调用的时候肯定提示要trycatch,如果一不小心,catch中没有重新抛出runtimeException,那就会出现事务不回滚的问题,而且此问题一般不易被发现。
总结一下:
1、spring做aop事务拦截的一般都会配置在service层;
2、service层一般情况下不能trycatch,有时候有检查行异常,那么就往上抛,如果又不想抛,那么就trycatch中在throw new RuntimeException("出错了!!!");
3、service层抛出的异常必须是runtimeException或者其子类的异常。
我让他把这个调用执行webservice的方法截图发给我,如下:
public Object[] send(String operationName,Object[] params,String endPoint) throws Exception { Object[] results = null; Client client = null; try { // 获取外部服务注册信息 Map<String, ExtWebserviceInfo> extMap = (Map<String, ExtWebserviceInfo>)SimpleCacheUtils.get(ExtWebService.WEBSERVICE); // 获取操作名称 if (!ToolUtil.isNullOrEmpty(extMap)) { // 获取服务方法名 String methodName = extMap.get(operationName).getServiceValue(); LOGGER.info("获取到方法标识为*"+operationName+"的操作名"+methodName); // 创建client client = new Client(new URL(endPoint)); LOGGER.info("监测到请求"+endPoint+"服务"+methodName+"操作方法的动作..."); // 执行调用 results = client.invoke(methodName, params); LOGGER.info("向"+endPoint+"服务"+methodName+"操作方法发出的请求成功..."); } } catch (Exception e) { LOGGER.info("向"+endPoint+"服务标识为"+operationName+"的操作方法发出的请求出现异常..."+e.getLocalizedMessage()); throw(Exception)new Exception().initCause(e); } finally{ if(client != null){ client.close(); } } return results; }
这个方法是一个调用执行webservice的方法,并返回执行结果给调用者,就是上面这个方法报错。我一看到这个代码,中有try catch,我想一定是这个方法中把异常给拦截了,service中捕获不到异常,导致aop拦截不到异常信息,导致事务不回滚。
但是仔细一看发现这个方法虽然捕获了异常,但是捕获后有重新抛出异常。
} catch (Exception e) { LOGGER.info("向"+endPoint+"服务标识为"+operationName+"的操作方法发出的请求出现异常..."+e.getLocalizedMessage()); throw(Exception)new Exception().initCause(e); } finally{
这不是又抛出异常了吗?应该没有问题了啊。
仔细分一下,就发现问题就出在这里,它抛出的是一个Exception,而spring在事务回滚时,是只对runtimeException或者其子类的异常才会回滚。
而且这里抛出的是一个Exception,别人调用的时候肯定提示要trycatch,如果一不小心,catch中没有重新抛出runtimeException,那就会出现事务不回滚的问题,而且此问题一般不易被发现。
总结一下:
1、spring做aop事务拦截的一般都会配置在service层;
2、service层一般情况下不能trycatch,有时候有检查行异常,那么就往上抛,如果又不想抛,那么就trycatch中在throw new RuntimeException("出错了!!!");
3、service层抛出的异常必须是runtimeException或者其子类的异常。
相关文章推荐
- Java学习之String类
- ant jar error:Execute failed: java.io.IOException: Cannot run program XXX ${aapt}
- Java调用net的webservice故障排除实战分享
- 【Java】substring的用法
- 为什么要设置Java环境变量(详解)
- Ext Chart图表保存为图片
- javax.imageio.IIOException: Not a JPEG file: starts with 0x47 0x49
- Java设计模式 -- Singleton模式
- Java 8 Stream Tutorial--转
- spring对AOP的支持
- Eclipse中将一个android项目当做另外一个android项目的library
- 详解Java中的clone方法 -- 原型模式
- Mybatis + SpringMVC事务管理
- Java- 装箱、枚举、注解
- 从零开始学Java之单例模式:懒汉模式和饱汉模式
- Java开发中Maven Jar包管理建议
- [leetcode-207]Course Schedule(java)
- java IDE idea 入门快捷键
- Java多线程 -- 线程的同步与锁
- struts2学习笔记——04