java 配置嵌套事务_Spring 事务嵌套的配置

问题

在使用Spring管理Service层事务时,会遇到service方法事务嵌套的问题。

默认情况下,service方法有自己独立的事务,如果一个复杂的service方法中,调用了多个事务操作,中间抛出异常时,往往不会发生事务回滚。这时候我们需要一种自动的方式来完成回滚。

Spring的事务传递机制

PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与 PROPAGATION_REQUIRED 类似的操作。

事务传递机制,有PROPAGATION_NESTED这样一个机制。

当我们在service方法中配置了这个方式

@Transactional(propagation=Propagation.NESTED)

public void save(Entity entity) {

//保存实体对象操作

}

运行之后系统异常, 提示当前配置不支持NESTED事务.

解决办法

查了一些代码后发现在HibernateTransactionManager中发现这样一段内容,其中有isNestedTransactionAllowed的判定。

protected Object doGetTransaction() {

HibernateTransactionObject txObject = new HibernateTransactionObject();

txObject.setSavepointAllowed(isNestedTransactionAllowed());

//...

}

所以在Hibernate配置中添加nestedTransactionAllowed的配置

然后所有的事务都自动使用嵌套事务了,也不需要修改任何service的代码和配置,可以在service方法上去掉(propagation=Propagation.NESTED)这段。

注意

PS : 当出现Unchecked Exception时,就会回滚整个Service事务.

注意

(1)必须是Unchecked Exception才回滚

(2) 即使调用了Hibernate session的flush方法,也会被回滚

你可能感兴趣的:(java,配置嵌套事务)