hfm*_*hfm 9 spring transactions jdbc savepoints
我有一个使用Hibernate连接数据库的JavaEE应用程序.在我的应用程序的某些部分,我调用了带有@Transactional
注释的方法.在某些情况下,我想回滚整个事务(外部服务方法调用和内部事务).在某些情况下,我想只回滚内部服务方法调用(即,回滚到内部方法开始时定义的保存点).
第一部分已经到位,但我对第二部分有疑问.当我执行以下操作时,我得到一个"UnexpectedRollbackException",消息"事务已回退,因为它已被标记为仅回滚".
@Service
public class OuterService{
@AutoWired
private InnerServcie innerService;
@Transactional
public void outer(){
try{
innerService.inner();
}catch(RuntimeException e){
//if i dont throw this up, it will give me the "UnexpectedRollbackException"
System.out.println("I cought a RuntimeException");
}
}
}
@Service
public class InnerServcie{
@Transactional
public void inner(){
//here we insert some data into db using hibernate
//but something goes wrong and an exception is thrown
}
}
Run Code Online (Sandbox Code Playgroud)
您正在寻找的功能称为保存点.严格来说,它们不是嵌套事务,而是后续SQL指令链中的里程碑,您可以回滚它们.回滚到保存点意味着从创建保存点时发出的所有指令无效,因此您可以拥有多个保存点,但是您只能在现在和保存点之间回滚指令,而不能在2个保存点之间回滚!
Spring在手动使用JdbcTransactionObjectSupport和使用@Transactional
注释时都支持保存点.
根据文件http://docs.spring.io/spring/docs/2.5.3/reference/transaction.html第9.5.7.3节你应该使用Propagation.NESTED
.
但是,您的情况可能无法使用这些选项.来自Javadoc:
注意:实际创建嵌套事务仅适用于特定事务管理器.开箱即用,这仅适用于处理JDBC 3.0驱动程序时的JDBC DataSourceTransactionManager.一些JTA提供程序也可能支持嵌套事务.
作为最后的手段,您可以直接发出/回滚到保存点的SQL指令.
对于PostgreSQL,它将是:
SAVEPOINT foo;
ROLLBACK TO SAVEPOINT foo;
Run Code Online (Sandbox Code Playgroud)
资料来源:http://www.postgresql.org/docs/8.2/static/sql-rollback-to.html
Spring/Hibernate/Java EE 不支持嵌套事务。因此,要么整个事务被回滚,要么内部事务实际上是一个新的、不同的事务,一旦成功就会立即提交,即使外部事务稍后回滚也是如此。
如果后者是您想要的,那么只需用以下注释您的内部方法即可
@Transactional(propagation = Propagation.REQUIRES_NEW)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9600 次 |
最近记录: |