Spring 引导:具有两个数据库的事务,如果第二个数据库失败,则回滚第一个数据库
Spring Boot: Transaction with two DB, rollback first DB if second DB fails
我正在构建一个 Spring 具有两个数据源的启动应用程序。我需要在 DB1 中进行更新,然后在 DB2 中进行更新。但是如果 DB2 的更新失败,DB1 更新应该回滚。
我看到 a post 遇到了同样的问题,但是 ChainedTransactionManager
实现对我不起作用。
我当前的实现是:
我有 2 个具有不同数据源的 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,但这就是问题所在,我有两个事务管理器。
我认为你应该在同一个方法updateBoth 中控制回滚DB1。在 spring 文档中你可以找到这个例子:
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() 启动一些可以在 catch 中捕获的自定义异常,然后使状态回滚。在这种情况下,假设您要手动回滚的是 DB1,则要使用的事务管理器是 dataSourceTransactionManagerSP (DB1)。你可以通过 @Transactional("dataSourceTransactionManagerBOL")
来控制 DB2 的事务
我正在构建一个 Spring 具有两个数据源的启动应用程序。我需要在 DB1 中进行更新,然后在 DB2 中进行更新。但是如果 DB2 的更新失败,DB1 更新应该回滚。
我看到 a post 遇到了同样的问题,但是 ChainedTransactionManager
实现对我不起作用。
我当前的实现是:
我有 2 个具有不同数据源的 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,但这就是问题所在,我有两个事务管理器。
我认为你应该在同一个方法updateBoth 中控制回滚DB1。在 spring 文档中你可以找到这个例子:
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() 启动一些可以在 catch 中捕获的自定义异常,然后使状态回滚。在这种情况下,假设您要手动回滚的是 DB1,则要使用的事务管理器是 dataSourceTransactionManagerSP (DB1)。你可以通过 @Transactional("dataSourceTransactionManagerBOL")
来控制 DB2 的事务