我们在项目中使用 Lift + Mapper(2.4 版)。我们也在使用每请求事务模式S.addAround(DB.buildLoanWrapper())。
在我们的一个请求中,我们需要嵌套事务,我们发现这是有问题的。我们发现可能的“黑客”之一是在单独的线程中启动事务(如下例所示),因为DB对象用于ThreadLocal管理当前连接和事务状态信息。
有没有比下面的更好(更安全且没有多线程)的实现?
  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