http://blog.csdn.net/liwf_/article/details/22791233
最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......
为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志。但是这边情况来了,当这个方法异常时候 日志是打印了,但是加的事务却没有回滚。
例:
类似这样的方法不会回滚(一个方法出错,另一个方法不会回滚):
if(userSave){ try { userDao.save(user); userCapabilityQuotaDao.save(capabilityQuota); } catch (Exception e) { logger.info("能力开通接口,开户异常,异常信息:"+e); } }
下面的方法回滚(一个方法出错,另一个方法会回滚):
if(userSave){
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
logger.info("能力开通接口,开户异常,异常信息:"+e);
throw new RuntimeException();
}
}
或者:
if(userSave){
try {
userDao.save(user);
userCapabilityQuotaDao.save(capabilityQuota);
} catch (Exception e) {
logger.info("能力开通接口,开户异常,异常信息:"+e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
为什么不会滚呢??是对Spring的事务机制就不明白。!!
默认spring事务只在发生未被捕获的runtimeexcetpion时才回滚。
spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获runtimeexception的异常,但可以通过
<tx:method name="upd*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
配置来捕获特定的异常并回滚
换句话说在service的方法中不使用try catch 或者在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被aop捕获进而回滚
解决方案:
方案1.例如service层处理事务,那么service中的方法中不做异常捕获,或者在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理
方案2.在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常(现在项目的做法)
相关推荐
4. 异常处理:为了触发事务回滚,方法内通常会抛出未检查异常(继承自`RuntimeException`的异常)或显式指定需要回滚的检查异常。Spring默认只在遇到未检查异常时自动回滚事务,如果需要在特定检查异常下回滚,可以...
其中,Callable 接口的 call 方法可以抛出异常,而 Runnable 接口的 run 方法不能抛出异常。因此,如果我们想捕获子线程的执行结果或异常,就应该使用 Callable 接口。 二、线程池的使用 在 Java 中,我们可以使用...
Spring AOP 的异常捕获原理是,当被拦截的方法抛出未被捕获的异常时,AOP代理会捕获这个异常并根据配置决定是否回滚事务。默认情况下,它只捕获 `RuntimeException` 及其子类。不过,我们可以通过自定义的事务切面...
然而,如果`methodB`的异常没有被捕获并重新抛出,而是被忽略或者处理了,那么Spring可能无法检测到这个异常,从而不会回滚`methodA`的事务。因此,捕获并重新抛出异常是至关重要的,如示例代码所示。 此外,需要...
Spring 异常捕获且回滚事务解决方案 在 Spring 框架中,异常捕获和回滚事务是非常重要的概念。今天,我们将讨论如何在 Spring 中捕获异常并回滚事务。 首先,让我们了解一下 Spring 的事务机制。当我们在 Spring ...
例如,如果你有一个方法声明了可能抛出IOException(这是一个检查异常),并且该方法在Spring的事务管理下执行,那么即使方法抛出了IOException,事务也不会自动回滚。相反,你需要显式地处理这个异常,比如通过try-...
如果在`try`块中抛出了需要回滚的异常,即使在`catch`块中没有再次抛出,事务仍会被回滚,因为Spring是在方法级别管理事务,而非`try-catch`块。 七、总结 `@Transactional`注解简化了Java开发中的事务管理,使得...
在这种情况下,子事务异常情况下,主事务捕获了子事务的异常却仍发生了回滚。从代码来看,回滚的原因在于,子事务失败的时候在回滚代码中设置了全局回滚的标识(AbstractPlatformTransactionManager.processRollback...
如果方法抛出未检查异常(继承自`RuntimeException`的异常)或者`Error`,Spring将会回滚事务;对于已检查异常(非`RuntimeException`),默认不会回滚,但可以通过`rollbackFor`属性指定需要回滚的异常类型。 2. *...
3. try-catch语句回滚:在try-catch语句中,如果catch块中抛出了异常,并且没有被处理,则事务会自动回滚。 需要注意的是,在try-catch语句中,如果catch块中对可能出现的异常进行了处理,没有再手动throw异常,...
4. **事务回滚规则**:在默认情况下,如果在@Transactional注解的方法中抛出未检查异常(继承自RuntimeException的异常)或Error,Spring会自动回滚事务。如果抛出的是受检异常(非RuntimeException),则不会自动...
- `NEVER`:总是运行在非事务环境中,如果当前存在事务,则抛出异常。 - `NESTED`:如果当前存在事务,则在嵌套事务内运行;如果没有事务,则行为类似于`REQUIRED`。 Spring事务管理的隔离级别包括: - `DEFAULT`...
这种方法通常在捕获到异常后并且不重新抛出时使用,以确保事务不会因为方法的“成功”执行而提交。 5. **异常处理与事务回滚**: 在`try-catch`块中,如果捕获到一个`RuntimeException`但没有重新抛出,Spring将...
- 默认情况下,只有在未捕获的`RuntimeException`或`Error`抛出时,Spring才会回滚事务。对于受检查的异常(即继承自`Exception`而非`RuntimeException`的异常),事务不会自动回滚。 - 如果希望在抛出特定受检查...
3. **异常回滚规则**:默认情况下,如果在@Transactional注解的方法中抛出未检查异常(继承自RuntimeException)或者Error,Spring会自动回滚事务。对于检查异常(非RuntimeException),如果不指定回滚规则,事务...
在这个例子中,`createUser`方法被标记为事务性的,如果在方法内部抛出未捕获的异常,Spring会自动回滚事务,确保数据一致性。 Spring事务管理的工作流程大致如下: 1. **AOP代理**:Spring使用AOP(面向切面编程)...
如果方法中抛出了未被捕获的异常,Spring会自动回滚事务;反之,如果方法正常结束,事务会被提交。 在Spring中,事务回滚规则基于异常类型。默认情况下,只有未检查异常(RuntimeException及其子类)会导致事务回滚...
如果当前不存在事务,`methodB`将抛出异常。这通常用于那些必须在一个事务上下文中执行的操作。 4. **PROPAGATION_REQUIRES_NEW** 无论当前是否存在事务,`methodB`都将创建一个新的事务。这意味着`methodB`内部...
例如,将异常捕获后未重新抛出unchecked异常,导致事务回滚的条件不成立。 5. 事务传播行为配置错误。比如,在需要REQUIRES_NEW传播行为的情况下配置了REQUIRED。 为了确保事务管理的有效性,开发者应该理解并正确...
浅谈Spring中@Transactional事务回滚及示例 @Transactional是Spring Framework中的一种事务管理机制,用于管理数据库事务。它可以使得数据库操作更加安全和可靠。本文将详细介绍@Transactional的使用场景、checked...