我正在构建一个具有两个数据源的Spring Boot应用程序。我需要先在DB1中进行更新,然后在DB2中进行更新。但是,如果DB2的更新失败,则应该回滚DB1的更新。
我看到a post遇到相同的问题,但是ChainedTransactionManager
实现对我来说不起作用。
我当前的实现是:
我为事务管理器提供了两个具有不同数据源的bean:
<bean id="dataSourceTransactionManagerSP" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" primary="true">
<constructor-arg ref="dataSourceSP"/>
</bean>
<bean id="dataSourceTransactionManagerBOL" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSourceBOL"/>
</bean>
我有两种进行更新的事务方法。由于某些奇怪的原因,@Transactional
注释在任何方法中均不起作用。但是到目前为止,这两种方法在其数据源中都可以很好地工作。
对于第一个数据库:
@Override
public Boolean updateDB1() {
transactionTemplate.setTransactionManager(dataSourceTransactionManagerSP);
return transactionTemplate.execute(status -> {
boolean r1 = repository1.update1();
boolean r2 = repository1.update2();
return r1 && r2;
});
}
对于第二个数据库:
@Override
public Boolean updateDB2() {
transactionTemplate.setTransactionManager(dataSourceTransactionManagerBOL);
return transactionTemplate.execute(status -> {
boolean r1 = repository2.update1();
boolean r2 = repository2.update2();
return r1 && r2;
});
}
但是现在我需要一个调用updateDB1
和updateDB2
的方法,如果DB2失败,则会回滚DB1。
@Override
public Boolean updateBoth() {
return transactionTemplate.execute(status -> {
boolean r1 = updateDB1();
boolean r2 = updateDB2();
return r1 && r2;
});
}
我知道这行不通,因为我需要指定TransactionManager,但这是问题所在,我有两个事务管理器。
答案 0 :(得分:1)
我认为您应该使用相同的updateBoth方法来控制回滚DB1。在春季Doc中,您可以找到以下示例:
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
updateOperation1();this is your updateDB1()
updateOperation2();-->this is your updateDB2()
} catch (SomeBusinessExeption ex) {
status.setRollbackOnly();
}
}
});
我将使updateDB2()启动一些自定义异常,该异常可能会被捕获,然后使状态回滚。在这种情况下,假设DB1是您要手动回滚的数据库,则要使用的事务管理器是dataSourceTransactionManagerSP(DB1)。您可以使用@Transactional(“ dataSourceTransactionManagerBOL”)控制DB2的事务