我正在开发一项微服务,其中涉及多个数据源。为了简化起见,我在这里使用两个数据源:MySql 和 Oracle。这是伪代码。
domain.withNewTransaction {
mySql.executeUpdate("update mySqlTable")
oracle.executeUpdate("update oracleTable")
}
有一天,在尝试提交oracle更新时出现异常,但是我发现mysql更新已成功提交并且没有回滚。我发现该框架正在使用ChainedTransactionManager.java来管理多个数据源提交。这是commit方法的代码。
public void commit(TransactionStatus status) throws TransactionException {
MultiTransactionStatus multiTransactionStatus = (MultiTransactionStatus) status;
boolean commit = true;
Exception commitException = null;
PlatformTransactionManager commitExceptionTransactionManager = null;
for (PlatformTransactionManager transactionManager : reverse(transactionManagers)) {
if (commit) {
try {
multiTransactionStatus.commit(transactionManager);
} catch (Exception ex) {
commit = false;
commitException = ex;
commitExceptionTransactionManager = transactionManager;
}
} else {
// after unsucessfull commit we must try to rollback remaining transaction managers
try {
multiTransactionStatus.rollback(transactionManager);
} catch (Exception ex) {
LOGGER.warn("Rollback exception (after commit) (" + transactionManager + ") " + ex.getMessage(), ex);
}
}
}
事实证明,当一个数据源提交失败时,ChainedTransactionManager 只会回滚剩余未提交的数据源,与已提交的事务无关。
我知道回滚已提交的事务是复杂且有风险的。我想知道应用程序开发人员是否有更好的想法来处理多数据源事务提交失败。提前致谢!
潇湘沐
相关分类