Spring事务异常回滚,try catch 捕获异常不回滚
在项目的开发过程中,service层都会有Spring事务管理,但是用了try catch之后,出现了不报错的方法了不会回滚的情况
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
}
在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
throw new RuntimeException();
}
在service层方法的catch语句中增加::TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常了
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
如果Service层过多的话,也可以写一个SpringUtil,加到工具类里面也行
public class SpringUtil implements ApplicationContextAware {
private static Logger logger = LoggerFactory.getLogger(SpringUtil.class);
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
try{
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
System.out.println(
"========ApplicationContext配置成功,在普通类可以通过调用ToolSpring.getAppContext()获取applicationContext对象,applicationContext="
+ applicationContext + "========");
}
}catch (Exception e){
logger.error("ApplicationContext配置"+e);
}finally {
}
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通过
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
//通过class获取Bean.
public static <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
/**
* 事务回滚机制
*/
public static void rollBack() {
try {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
} catch (Exception e) {
e.printStackTrace();
}
}
}
其实像第一种try catch这种把整个包裹起来,这种业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出,全被捕获并“吞掉”,导致spring异常抛出触发事务回滚策略失效。
如果在catch代码块中采用页面硬编码的方式使用spring api对事务做显式的回滚,这样写也是可以的