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

时间:2016-06-21 18:33:54

标签: java spring jpa jms

我有两个交易管理员: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 个答案:

答案 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
   }
}