Spring - 在JPA事务之后提交JMS事务

3
我有两个事务管理器:JpaTransactionManagermyJpaTm)和JmsTransactionManagermyJmsTm)。
考虑下面的代码:
@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,但我希望通过将两个事务连接起来来解决它。
2个回答

2
我还发现了另一种选择 - 我们可以使用 spring-data-commons 中的 ChainedTransactionManager 来按正确顺序链接两个事务管理器。
@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
   }
}

1

我曾经使用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();
                 }
         });
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接