Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept transaction only when is sure to be committed but before is committed

Context is Java - JPA with Hibernate and Spring.

Let's take the scenario of two-phase commit protocol (but only with one resource):

  1. Query to commit from application

  2. Vote Yes/No (from database in our case)

3.1. If yes from database

3.1.1. (Make callback in code) - not part of the protocol

3.1.2. Commit to database

3.2 If no

3.2.1 Rollback to database

What I want is a way to do the callback from 3.1.1 in code, but only when it is known that the transaction will be committed, but before is actually committed. Also, if an exception is thrown here, then the transaction should be be rolled-back.

Using TransactionSynchronization (*) from Spring, allows you to intercept a transaction before it is committed/completed or after it was committed/completed.

  • beforeCommit() callback says that a rollback can still occur after the method was called;
  • beforeComplete() is called even if transaction is failing
  • afterCommit/Complete() is called after transaction was actually committed to database and there is no way to rollback.

Now that I look it seems that what I want is another in a full two-phase commit protocol; but I'm wondering if there is a workaround in Spring. The difference is that the call done in the callback cannot be rolled back.

(*) from Spring 4.2 is very simple with @TransactionalEventListener and TransactionPhase which nicely abstracts TransactionSynchronization

like image 343
Random42 Avatar asked Aug 31 '16 15:08

Random42


People also ask

What means rollback only?

However, the application should not attempt to rollback the transaction directly. Instead, it should mark the transaction for rollback only, which sets a flag on the transaction indicating that the transaction cannot be committed.

What is the meaning of@ Transactional annotation?

The @Transactional annotation is the metadata that specifies the semantics of the transactions on a method. We have two ways to rollback a transaction: declarative and programmatic. In the declarative approach, we annotate the methods with the @Transactional annotation.

What is unexpected rollback exception?

public class UnexpectedRollbackException extends TransactionException. Thrown when an attempt to commit a transaction resulted in an unexpected rollback.

What are the types of the transaction management Spring supports?

Spring supports both programmatic and declarative transaction management.


1 Answers

Your case is that one of your resource is not compatible with two-phase-commit (not XA-capable). Your idea goes in the direction of the pattern described in paragraph XA and the Last Resource Gambit of http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html

The use of the last resource gambit is briefly explained in the answer of How to set up Spring Boot + Bitronix + non-XA Datasource + XA JMS Connection

By the way, your question doesn't mention which implementation of a transaction manager you use (JBossTS, Bitronix JTA, Atomikos Transaction Essentials, ...).

like image 164
Florian H. Avatar answered Oct 12 '22 03:10

Florian H.