How to enforce creating new transaction in Lift Mapper?

370 views Asked by At

We are using Lift + Mapper (version 2.4) in our project. We as well are using transaction-per-request pattern S.addAround(DB.buildLoanWrapper()).

In one of our requests we need to have nested transaction which we found to be problematic. We found that one of possible 'hacks' is to start transaction in a separate thread (like in example below) because DB object uses ThreadLocal to manage current connection and transaction state info.

Is there any implementation that is better (more safer and without multi-threading) than the one bellow?

  import net.liftweb.db.{DefaultConnectionIdentifier, DB}
  import akka.dispatch.Future

  /**
   * Will create a new transaction if none is in progress and commit it upon completion or rollback on exceptions.
   * If a transaction already exists, it has no effect, the block will execute in the context
   * of the existing transaction. The commit/rollback is handled in this case by the parent transaction block.
   */
  def inTransaction[T](f: ⇒ T): T = DB.use(DefaultConnectionIdentifier)(conn ⇒ f)

  /**
   * Causes a new transaction to begin and commit after the block’s execution,
   * or rollback if an exception occurs. Invoking a transaction always cause a new one to be created,
   * even if called in the context of an existing transaction.
   */
  def transaction[T](f: ⇒ T): T = Future(DB.use(DefaultConnectionIdentifier)(conn ⇒ f)).get
1

There are 1 answers

0
nafg On

Unfortunately there doesn't seem to be an existing API. You can ask about adding one on the google group. However there's nothing stopping you from doing something like:

DB.use(DefaultConnectionIdentidier){ sc =>
  val conn: java.sql.Connection = sc.connection
  // use regular JDBC mechanism here
}