Reputation: 3331
I have two transaction managers: JpaTransactionManager
(myJpaTm
) and JmsTransactionManager
(myJmsTm
).
Consider following code:
@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
}
}
We have outer JPA transaction and inner JMS transaction, both are separated because we are not using distributed transactions.
I would like to commit JMS transaction right after committing JPA transaction. In this case current JMS transaction would need to hook up to parent JPA transaction.
I'am not looking for substitution to distributed transactions, I just would like to send JMS messages after committing data to database.
I know that I just could create another class that could call methoda
and afterwards methodb
, but I would like to solve it by connection both transactions together.
Upvotes: 3
Views: 2307
Reputation: 3331
I've found also another option - we can use ChainedTransactionManager
from spring-data-commons
that will chain two transaction managers in proper order.
@Configuration
public class ChainedTransactionConfiguration {
@Bean
public ChainedTransactionManager chainedTransactionManager(
@Named("myJpaTm") JpaTransactionManager myJpaTm,
@Named("myJmsTm") JmsTransactionManager myJmsTm) {
return new ChainedTransactionManager(myJmsTm, myJpaTm);
}
}
now I have to only set new 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
}
}
Upvotes: 2
Reputation: 3943
I have done this in past using TransactionSynchronizationManager and adding the send message block in afterCommit method for the synchronization. Basically you need to place something like this in your implementation:
@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();
}
});
}
}
}
Upvotes: 1