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?
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
.