Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何在Lift Mapper中强制创建新事务?_Scala_Transactions_Lift_Lift Mapper - Fatal编程技术网

Scala 如何在Lift Mapper中强制创建新事务?

Scala 如何在Lift Mapper中强制创建新事务?,scala,transactions,lift,lift-mapper,Scala,Transactions,Lift,Lift Mapper,我们在项目中使用Lift+Mapper(版本2.4)。我们还使用每个请求的事务模式S.addAround(DB.buildLoanWrapper()) 在我们的一个请求中,我们需要有嵌套的事务,我们发现这是有问题的。我们发现可能的“黑客”之一是在单独的线程中启动事务(如下面的示例),因为DB对象使用ThreadLocal来管理当前连接和事务状态信息 有没有比下面的实现更好(更安全,没有多线程)的实现 import net.liftweb.db.{DefaultConnectionIdenti

我们在项目中使用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

不幸的是,似乎没有一个现有的API。你可以询问在谷歌群组中添加一个。但是,没有什么可以阻止您执行以下操作:

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

使用
Future(…).get
完全没有意义,因为它使用两个线程而不是一个线程;请删除它和Akka标签,因为这个问题与Akka无关。您所说的“更好”实现是什么意思?如果你使用纯squeryl,你可以自己决定。如果您只使用Mapper,AFAIK,您也可以为自己选择事务范围。对罗兰·库恩(Roland Kuhn):此处使用Future正是为了创建一个单独的执行描述线程,因为它缺少必要的解释,即:如果您使用loan wrapper围绕您的请求使用DB.use,那么它就是其中之一(我还不知道另一种)如何强制新事务的方法。由于使用线程局部变量,simple nested DB.use完全不起任何作用