Tuesday, November 24, 2009

Use Closures for Transactions in Groovy

Groovy closures are a handy tool for making your code reusable. One place I have found them particularly useful is in executing database transactions.

Ideally, transactions management should be handled at the level of AOP, filter, or interceptor that has no knowledge of a specific action execution. However, it is often necessary to implement transactions in a specific isolated scope; such as when you have to process a large collection of records. In such a case, when you need to commit your transaction for each record processed; your code is likely to always use the same cut and paste transaction management code.

In a typical Java application that uses Hibernate, you will often see code like this repeated through out the application:



Transaction tr = session.beginTransaction()
try {
// update some object
book.title = "Foo Bar"
session.save(book)

tr.commit()
} catch(Throwable t) {
tr.rollback()
log.error("ERROR",t)
}



It's always the same code, but grandpa's Java syntax doesn't make it easy to reuse this code. With Groovy, you write this code once and wrap your code in a closure anytime you require a transaction.

So a new execution looks like this:


def closure = {
// update some object
book.title = "Foo Bar"
session.save(book)
}

doWithTransaction(closure)


Here is your reusable transaction management code:



def doWithTransaction = { def closure ->

Transaction tr = session.beginTransaction()
try {
closure()
tr.commit()
} catch(Throwable t) {
tr.rollback()
log.error("ERROR",t)
}
}


This is just another way Groovy closures can help clean up your code base. Using closures in this manner makes it easier to increase your code coverage, since you will only need to write one test case to test the reused transaction code. If you have large code base, these small changes can really help.

0 comments:

Post a Comment