Transaction Management

karthikprasad13 edited this page Jun 8, 2015 · 3 revisions
Clone this wiki locally

Transaction handling in NoSQL is challenging. Most of them don't provide a way to ensure atomicity and concurrency and it's programmer's responsibility to ensure those cases where things may go wrong. It gets complicated when more than one data-stores are involved (cross-datastore persistence).

Kundera, being a JPA provider supports Transaction Management. There are two ways you can achieve this:

EntityTransaction Methods

javax.persistence.EntityTransaction interface provides following methods for defining transaction boundaries and managing transactions on operations.

  public abstract void begin();
  public abstract void commit();
  public abstract void rollback();
  public abstract void setRollbackOnly();
  public abstract boolean getRollbackOnly();
  public abstract boolean isActive();

EntityManagerImpl class in Kundera implements both javax.persistence.EntityManager and javax.persistence.EntityTransaction. This means they are available to you for use, just the way you use them in enterprise java application in relational world.

Here is an example:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("cassandra_pu");
EntityManager em = emf.createEntityManager();
em.setFlushMode(FlushModeType.COMMIT);   //Necessary for flusing on transaction commit, AUTO option flushes automatically

Person p1 = new Person("1", "Amresh");
Person p2 = new Person("2", "Vivek");
Person p3 = new Person("3", "Kuldeep");


em.getTransaction().commit();  //Will write p1, p2, p3 to database

Person pp1 = em.find(Person.class, "1");    //Not null
Person pp2 = em.find(Person.class, "2");    //Not null
Person pp3 = em.find(Person.class, "3");    //Not null

em.getTransaction().begin();  //begin new transaction

p2.setPersonName("Junk value");
pp2 = em.find(Person.class, "2");    //Not null, and person name still "Vivek"

Refer to test case EntityTransactionTest for more on this.

Java Transaction API (JTA)

JTA is de-facto industry standard for transaction management (especially in container-managed environment). Kundera supports JTA and it works seamlessly with Spring too.

javax.transaction.UserTransaction interface provides following methods for defining transaction boundaries and managing transactions on operations.

  public abstract void begin() throws NotSupportedException, SystemException;
  public abstract void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException;
  public abstract void rollback() throws IllegalStateException, SecurityException, SystemException;
  public abstract void setRollbackOnly() throws IllegalStateException, SystemException;
  public abstract int getStatus() throws SystemException;
  public abstract void setTransactionTimeout(int paramInt) throws SystemException;

KunderaJTAUserTransaction class in Kundera implements this interface. This makes it possible for container to call UserTransaction methods for transaction management.

We have built a web application called twitample (available on Github here). It runs in tomcat and uses JTA on all data-store operations. Feel free to run this and see code to get a feel of it.