Spring中避免事务回滚

maq*_*jav 4 java spring jpa jdbc

假设我有下一个代码:

@Autowired
private IManager1 manager1;

@Autowired
private IManager2 manager2;

@Autowired
private IManager3 manager3;

@Transactional
public void run() {
     manager1.doStuff();
     manager2.registerStuffDone();

     manager3.doStuff();
     manager2.registerStuffDone();

     manager1.doMoreStuff();
     manager2.registerStuffDone();
}
Run Code Online (Sandbox Code Playgroud)

如果启动任何异常,我想回滚“doStuff()”方法完成的所有操作,但我不想回滚“registerStuffDone()”方法记录的数据。

我一直在阅读 @Transactional 注释的传播选项,但我不明白如何正确使用它们。

每个经理在内部都使用 hiberante 来提交更改:

@Autowired
private IManager1Dao manager1Dao;

@Transactional
public void doStuff() {
    manager1Dao.doStuff();
}
Run Code Online (Sandbox Code Playgroud)

dao 看起来像这样:

@PersistenceContext
protected EntityManager entityManager;

public void doStuff() {
    MyObject whatever = doThings();
    entityManager.merge(whatever);
}
Run Code Online (Sandbox Code Playgroud)

这是我的 applicationContext 配置:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSourcePool" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
</bean>

<bean id="entityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
Run Code Online (Sandbox Code Playgroud)

有想法吗?

Ess*_*Boy 5

您需要 2 个事务,一个用于要提交的内容,另一个用于要回滚的内容。

@Transactional(propagation = Propagation.REQUIRES_NEW, noRollbackFor={Exception1.class, Exception2.class})
public void registerStuffDone()() {
   //code
}
Run Code Online (Sandbox Code Playgroud)

然后,您的 run 方法将使用第一个事务并将其回滚,但 registerStuffDone 方法将启动第二个事务并将其提交。