Ond*_*cka 6 spring hibernate transactions rollback
我正在使用Hibernate + spring + @Transactional
annotations来处理我的应用程序中的事务.
事务管理器声明如下:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
Run Code Online (Sandbox Code Playgroud)
这在大多数情况下效果很好,但是我发现了一个问题,我有两种方法,都注释了@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
}
}
}
Run Code Online (Sandbox Code Playgroud)
和
package temp;
import org.springframework.transaction.annotation.Transactional;
public class InnerTestService {
@Transactional
public void innerTestMethod() throws RuntimeException {
throw new RuntimeException();
}
}
Run Code Online (Sandbox Code Playgroud)
当我调用OuterTestService#outerMethod()时,我得到一个异常
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
Run Code Online (Sandbox Code Playgroud)
由于只有一个事务(没有嵌套事务),整个outerTestMethod()
事务被标记为仅回滚.
我发现我可以使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
但是必须在每种方法上明确使用它.因为在测试期间(滚动)不会引发此错误,所以这是不可接受的.
我的问题 - 是否有一种方法可以自动(例如,不明确地为每个方法设置)只有当从启动事务的方法(在这种情况下,outerTestMethod()
)中引发异常时才会回滚事务?
aba*_*ogh 11
创建另一个注释,例如@NoRollbackTransactional
:
@Transactional(noRollbackFor = RuntimeException.class)
public @interface NoRollbackTransactional {
}
Run Code Online (Sandbox Code Playgroud)
并在你的方法上使用它.另一方面,我同意Donal的评论,你应该修改你的交易范围,@Transactional
从另一方面调用通常不是一个好主意@Transactional
.
您可能还需要关闭globalRollbackOnParticipationFailure.
当我在周围的交易中进行独立交易时,我遇到了这个问题.当独立事务失败时,它也失败了周围的事务.
关闭参与标志为我解决了这个问题:
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="globalRollbackOnParticipationFailure" value="false" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
28222 次 |
最近记录: |