2016-06-21 112 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 
    } 
}