2016-06-21 115 views
1

我有两个事务管理器:JpaTransactionManagermyJpaTm)和JmsTransactionManagermyJmsTm)。Spring - 在JPA事务后提交JMS事务

考虑下面的代码:

@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

我已经在过去使用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(); 
       } 
     }); 
    } 
    } 
} 
0

我还发现另一种选择 - 我们可以使用ChainedTransactionManagerspring-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 
    } 
}