我有两个交易管理员:JpaTransactionManager
(myJpaTm
)和JmsTransactionManager
(myJmsTm
)。
请考虑以下代码:
@Named
public class TestA {
@Inject TestB testB;
@Transactional(transactionManager="myJpaTm")
public void methoda() {
// store stuff in db
testB.methodb();
}
}
@Named
public class TestB {
@Transactional(transactionManager="myJmsTm")
public void methodb() {
// send few JMS messages
}
}
我们有外部JPA事务和内部JMS事务,两者都是分开的,因为我们没有使用分布式事务。
我想在提交JPA事务后立即提交JMS事务。在这种情况下,当前的JMS事务需要连接到父JPA事务。
我不是在寻找分布式事务的替代,我只是想在将数据提交到数据库之后发送JMS消息。
我知道我可以创建另一个可以调用methoda
然后调用methodb
的类,但我想通过连接两个事务来解决它。
答案 0 :(得分:0)
我以前使用TransactionSynchronizationManager并在afterCommit方法中添加发送消息块进行同步。基本上你需要在你的实现中放置这样的东西:
@Named
public class TestA{
@Inject
TestB testB;
@Transactional(transactionManager="myJpaTm")
public void methoda() {
// other db stuff
if(TransactionSynchronizationManager.isActualTransactionActive()){
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){
@Override
public void afterCommit(){
testB.methodb();
}
});
}
}
}
答案 1 :(得分:0)
我还发现了另一种选择 - 我们可以使用ChainedTransactionManager
中的spring-data-commons
来按正确顺序链接两个交易管理器。
@Configuration
public class ChainedTransactionConfiguration {
@Bean
public ChainedTransactionManager chainedTransactionManager(
@Named("myJpaTm") JpaTransactionManager myJpaTm,
@Named("myJmsTm") JmsTransactionManager myJmsTm) {
return new ChainedTransactionManager(myJmsTm, myJpaTm);
}
}
现在我只需要设置新TM:
@Named
public class TestA {
@Inject TestB testB;
@Transactional(transactionManager="chainedTransactionManager")
public void methoda() {
// store stuff in db
testB.methodb();
}
}
@Named
public class TestB {
@Transactional(transactionManager="myJmsTm")
public void methodb() {
// send few JMS messages
}
}