Easy transactions using Spring JDBC?

letronje picture letronje · Jun 21, 2009 · Viewed 14.8k times · Source

I am working on a Java app that uses Spring IoC and JDBC Template classes. I have a DAO class that has 4 methods : m1() to m4(). m1 performs multiple inserts and updates on table t1, m2 on table t2, m3 on t3, etc.

The DAO methods are used as follows:

while(true)
{
  //process & generate data

  dao.m1(data1);
  dao.m2(data2);
  dao.m3(data3);
  dao.m4(data4);

  //sleep
}

I want the db operations under the 4 consecutive method calls to be atomic, either all the 4 tables are updated successfully or none are. So, if there is an error while performing operations in m3(), i want to rollback all the changes(updates & inserts) performed in m2 & m1.

So does spring let you do it the following way ?

while (true)
{
  //process & generate data

  transaction = TransactionManager.createNewTransaction();

  transaction.start()

  try
  {
    dao.m1(data1);
    dao.m2(data2);
    dao.m3(data3);
    dao.m4(data4);
  }
  catch(DbUpdateException e)
  {
    transaction.rollBack();
  }

  transaction.end();

  // sleep

}

or are there better ways to do it?

Answer

cletus picture cletus · Jun 21, 2009

Yes Spring allows you to programmatically control transactions.

Personally I prefer declarative transactions using annotations, which goes like this:

public void runBatchJob() {
  while (true) {
    // generate work
    doWork(unitOfWork);
  }
}

@Transactional
private void doWork(UnitOfWork work) {
  dao.m1(data1);
  dao.m2(data2);
  dao.m3(data3);
  dao.m4(data4);
}

where the DAO functions are defined:

@Transactional
public void m1(Data data) {
  ...
}

This requires in your applicationContext.xml:

<tx:annotation-driven/>

Declarative transactions can be declared to require a transaction, require a new transaction, support transactions, etc. Rollback will occur when a block annotated with @Transactional throws a RuntimeException.