问题描述
我使用Hibernate + spring + @Transactional
注解来处理我的应用程序中的事务。
事务经理声明如下:
< bean id =transactionManagerclass =org.springframework.orm.hibernate3.HibernateTransactionManager >
< property name =sessionFactoryref =sessionFactory/>
< / bean>
< tx:注解驱动的事务管理器=transactionManager/>
这在大多数情况下效果很好,但我发现一个问题,我有两种方法,两种注释@Transactional:
package temp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
public class OuterTestService {
@Autowired
private InnerTestService innerTestService;
@Transactional
public void outerMethod(){
try {
innerTestService.innerTestMethod();
} catch(RuntimeException e){
//这里的一些代码
}
}
}
和
package temp;
import org.springframework.transaction.annotation.Transactional;
public class InnerTestService {
@Transactional
public void innerTestMethod()抛出RuntimeException {
throw new RuntimeException();
当我调用OuterTestService#outerMethod()时,一个异常
org.springframework.transaction.UnexpectedRollbackException:事务回滚,因为它已被标记为仅回退
由于只有一个事务(没有嵌套事务),整个 outerTestMethod()
code>的交易被标记为仅回滚。
我发现我可以使用noRollbackFor轻松解决这个问题:
package cz.csas.pdb.be.service.tempdelete;
import org.springframework.transaction.annotation.Transactional;
public class InnerTestService {
@Transactional(noRollbackFor = RuntimeException.class)
public void innerTestMethod()抛出RuntimeException {
throw new RuntimeException() ;
}
}
但是这必须在每种方法中明确使用。因为这个错误在测试期间没有被提出(这是回滚的),所以这是不可接受的。
我的问题 - 有没有办法自动(例如,每个方法)设置只有在启动事务的方法引发异常时才会回滚事务(在这种情况下, outerTestMethod()
)?
创建另一个注释,例如 @NoRollbackTransactional
,类似于:
@Transactional(noRollbackFor = RuntimeException。类)
public @interface NoRollbackTransactional {
}
然后在你的方法。另一方面,我同意Donal的评论,你应该修改你的交易范围,从另一个调用
。 @Transactional
通常不是一个好主意。 @Transactional
I'm using Hibernate + spring + @Transactional
annotations to handle transactions in my application.
Transaction manager is declared as follows:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
This works well in most cases, but I've found a problem where I have 2 methods, both annotated @Transactional:
package temp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
public class OuterTestService {
@Autowired
private InnerTestService innerTestService;
@Transactional
public void outerMethod() {
try {
innerTestService.innerTestMethod();
} catch (RuntimeException e) {
// some code here
}
}
}
and
package temp;
import org.springframework.transaction.annotation.Transactional;
public class InnerTestService {
@Transactional
public void innerTestMethod() throws RuntimeException {
throw new RuntimeException();
}
}
When I invoke OuterTestService#outerMethod(), I get an exception
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
As there is only one transaction (no nested transactions), the whole outerTestMethod()
's transaction is marked as rollback-only.
I've found that I can easily overcome this using noRollbackFor:
package cz.csas.pdb.be.service.tempdelete;
import org.springframework.transaction.annotation.Transactional;
public class InnerTestService {
@Transactional(noRollbackFor = RuntimeException.class)
public void innerTestMethod() throws RuntimeException {
throw new RuntimeException();
}
}
But this has to be explicitly used on every method. Because this error is not raised during tests (which are rollbacked), this is not acceptable.
My question -- is there a way to automatically (eg. not explicitly for every method) set that transactions are rolled back only when an exception is raised from method which started the transaction (in this case, the outerTestMethod()
)?
Create another annotation, e.g. @NoRollbackTransactional
, something like:
@Transactional(noRollbackFor = RuntimeException.class)
public @interface NoRollbackTransactional {
}
And use this on your methods. On the other hand I agree with Donal's comment, you should revise your transaction scopes, imho it is generally not a good idea to call @Transactional
from another @Transactional
.
这篇关于只有在子方法中发生异常时才进行事务回滚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!