为所有Spring托管事务注册beforeCommit回调
我使用ChainedTransactionManager跨ActiveMQ和MySQL实现Best Effort 1PC,在我的示例中,数据库事务首先提交。为了减少失败窗口,我想在提交数据库事务之前检查ActiveMQConnection是否失败。一旦使用TransactionSynchronizationManager.registerSynchronization启动事务,我就可以执行此操作,但我想要的是注册为每个事务运行的代码块,而无需在代码中执行此操作 我可以将ChainedTransactionManager子类化,但这似乎不是最干净的。有更好的方法吗为所有Spring托管事务注册beforeCommit回调,spring,spring-transactions,Spring,Spring Transactions,我使用ChainedTransactionManager跨ActiveMQ和MySQL实现Best Effort 1PC,在我的示例中,数据库事务首先提交。为了减少失败窗口,我想在提交数据库事务之前检查ActiveMQConnection是否失败。一旦使用TransactionSynchronizationManager.registerSynchronization启动事务,我就可以执行此操作,但我想要的是注册为每个事务运行的代码块,而无需在代码中执行此操作 我可以将ChainedTransa
编辑:看来子类化ChainedTransactionManager不是一个好主意,因为它依赖于非公共的MultiTransactionStatus。创建一个新的平台TransactionManager,将其委托给ChainedTransactionManager是一种替代方法。这就是我决定实施它的方式:
import org.apache.activemq.ActiveMQConnection;
import org.springframework.data.transaction.ChainedTransactionManager;
import org.springframework.jms.connection.JmsResourceHolder;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
public class JmsTransportFailureHandlingTransactionManager implements PlatformTransactionManager {
private final ChainedTransactionManager chainedTransactionManager;
public JmsTransportFailureHandlingTransactionManager(ChainedTransactionManager chainedTransactionManager) {
this.chainedTransactionManager = chainedTransactionManager;
}
@Override
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
TransactionStatus transaction = chainedTransactionManager.getTransaction(definition);
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void beforeCommit(boolean readOnly) {
for (Object resource : TransactionSynchronizationManager.getResourceMap().values()) {
if (resource instanceof JmsResourceHolder) {
ActiveMQConnection connection = (ActiveMQConnection) ((JmsResourceHolder) resource).getConnection();
if (connection.isTransportFailed()) {
throw new IllegalStateException("ActiveMQ transport failed.");
}
}
}
}
});
return transaction;
}
@Override
public void commit(TransactionStatus status) throws TransactionException {
chainedTransactionManager.commit(status);
}
@Override
public void rollback(TransactionStatus status) throws TransactionException {
chainedTransactionManager.rollback(status);
}
}