5

In our new project we would like to achieve transactions that involve jpa (mysql) and a message bus (rabbitmq)

We started building our infrastructure with spring data using mysql and rabbitmq (via spring amqp module). Since rabbitMq is not XA-transactional we configured the neo4j chainedTransactionManager as our main transactionManager. This manager takes as argument the jpa txManager and the rabbitTransactionManager.

Now, I do get the ability to annotate a service with @Transacitonal and use both the jpa and rabbit inside it. If I throw an exception within the service then none of the actions actually occur.

Here are my questions:

  1. Is this configuration really gives me an atomic transaction?
  2. I've heard that the chained tx manager is not using a 2 phase commit but a "best effort", is this best effort less reliable? if so how?
AGan
  • 457
  • 5
  • 12
Urbanleg
  • 6,252
  • 16
  • 76
  • 139

1 Answers1

3

What the ChainedTransactionManager does is basically start and commit transactions in reverse order. So if you have a JpaTransactionManager and a RabbitTransactionManager and configured it like so.

@Bean
public PlatformTransactionManager transactionManager() {
    return new ChainedTransactionManager(rabbitTransactionManager(), jpaTransactionManager());
}

Now if tha JPA commit succeeds but your commit to rabbitMQ fails your database changes will still be persisted as those are already committed.

To answer your first question it doesn't give you a real atomic transaction, everything that has been committed prior to the occurence of the Exception (on committing) will remain committed.

See http://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/transaction/ChainedTransactionManager.html

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • Is it possible to achieve a single transaction with both datasources rolling back on fail of one of them? – Urbanleg Dec 12 '13 at 11:44
  • No... A commit is permanent. The only way around this would be to do a compensating transaction (i.e. keep track of the changes yourself and manually rollback). – M. Deinum Dec 12 '13 at 11:49
  • what about jta? without chained manager and without rabbit.? (i.e with active mq instead?) – Urbanleg Dec 12 '13 at 11:52
  • JTA is a distributed transaction manager so that should work, but is the additional overhead needed? How often do you expect things to go wrong, yuo could, for instance, commit database first and when committing/sending messages goes wrong, try to resend (later) the messages (or vice-versa). – M. Deinum Dec 12 '13 at 12:11
  • Transactions are not about probabilities. They are about correctness. Having logical corrupt data is generally not an option. So if you need to update more than one datasource, you need to use XA or distributed transactions. – steve Dec 17 '13 at 06:04
  • Read about transactions with and without XA (2PC) strategies on http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html . It provides a good overview over the needs and risque's of both invariants. It says about 1PC: "The basic idea is to delay the commit of all resources as late as possible in a transaction so that the only thing that can go wrong is an infrastructure failure (not a business-processing error)" – Picrochole Aug 03 '15 at 18:30
  • ChainedTransactionManager is now deprecated – iTake Apr 28 '21 at 14:03