Propagation.REQUIRES_NEW不会在Spring中使用JPA创建新事务

我有以下情况。 我正在使用JPA,Spring:

@Autowired SampleService service; @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public void PerformLogic(LogicData data) throws SIASFaultMessage { SampleObject so = createSampleObject(); try{ .//do some logic to persist things in data . . persistData(data); . . . updateSampleObject(so); } catch(Exception){ updateSampleObject(so); throw new SIASFaultMessage(); } } @Transactional(propagation = Propagation.REQUIRES_NEW) public createSampleObject() { SampleObject so = new SampleObject(); . .//initialize so . service.persist(so); return so; } @Transactional(propagation = Propagation.REQUIRES_NEW) public updateSampleObject(SampleObject so) { service.persist(so); return so; } 

当一切正常时,数据会持久保存在数据库中而不会出现问题。 但是,当抛出exception时,我需要方法updateSampleObject(so)将信息保存在数据库中。 这不是正在发生的事情。 如果抛出exception,方法updateSampleObject也会回滚,这不是我需要的。 我需要这两个方法( createSampleObjectupdateSampleObject )始终保持持久化,无论是否抛出exception。 我怎样才能做到这一点?

此外,如果我使用以下方法来激活方法createSampleObjectupdateSampleObject

 @Transactional(propagation = Propagation.NEVER) 

这个想法是抛出一个exception,我没有抛出任何exception。 哪里有问题? 分析日志我看到这一行:

 org.springframework.orm.jpa.JpaTransactionManager ==> Creating new transaction with name [com.test.PerformLogic]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT.... 

这意味着创建了此事务,但我没有看到其他事务的提示。

这是Spring关于事务的配置文件的一部分

             ${hibernate.dialect} true ${hdm2ddl.auto}           

Spring事务是基于代理的。 因此,当bean A导致bean B的事务时它是如何工作的。事实上,它实际上是对代理的引用,代理委托给bean B.这个代理是启动并提交/回滚事务的代理:

 A ---> proxy ---> B 

在您的代码中,A的事务方法调用A的另一个事务方法。因此Spring无法拦截调用并启动新事务。 这是一个常规方法调用,不涉及任何代理。

因此,如果您希望启动一个新事务,则createSampleObject()方法应该位于另一个bean中,并注入到当前bean中。

这在文档中有更详细的解释。

我的猜测是,由于两个方法都在同一个bean中,Spring的AOP没有机会拦截create / updateSampleObject方法调用。 尝试将方法移动到单独的bean。