3

我想实现实用函数/monad/aspect 来管理 scala 中的休眠事务,并寻找有关最佳方法的建议。

首先,我尝试创建如下柯里化函数:

def session() = sessionFactory.getCurrentSession()

def transaction() = session().getTransaction()

def tx[A, B](f: A => B)(a: A): B = {
try {
  session().beginTransaction()
  val r = f(a)
  transaction().commit()
  return r
} catch {
  case e: 
    Throwable => 
      transaction().rollback()
      throw e
} finally {
  session.close()      
}

}

我的想法是我可以使用此功能执行以下操作:

def saveMyEntity() {
  session().save(new MyEntity)
}

tx(saveMyEntity)()

并且 saveMyEntity 调用将被包装到事务中。

不幸的是,我收到以下代码错误:

[error]  found   : () => Unit
[error]  required: ? => ?
[error]   tx(saveMyEntity)()

我仍在学习 scala,并寻求改进我的方法的建议。也许我可以以某种方式修改我的功能以获得更好的结果?或者添加另一个单元类型特定功能?还是选择另一条路?

有任何想法吗?任何scala规范的方式来实现这个?谢谢。

4

2 回答 2

3

方法tx接受 1 个参数的函数作为参数,方法saveMyEntity不接受任何参数,因此您不能将其用作A => B(1 个参数的函数)。

您没有单独使用aand f,因此不需要 in a。您可以在此处使用按名称参数:

def tx[B](f: => B): B = {

如果你想使用 a saveMyEntityasUnit => Unit你应该明确地创建函数:

tx[Unit, Unit](_ => saveMyEntity)(())

我猜一些更改可能会提高您的代码可读性:

import util.control.Exception.allCatch

def withSession[T](f: Session => T):T = {
  val session = ??? // start session here
  allCatch.anfFinally{
    session.close()
  } apply { f(session) }
}

def inTransaction[T](f: => T): T =
  withSession{ session =>
    session().beginTransaction()
    try {
      val r = f(a)
      transaction().commit()
      r
    } catch {
      case e: Throwable => 
        transaction().rollback()
        throw e
    }
  }

inTransaction{saveMyEntity}
于 2013-07-08T06:51:34.487 回答
0
object TestTransaction
{
  def executeInTransaction(f: => Unit)={
    println("begin")
    f
    println("end")
  }
  executeInTransaction {
    println("action!")
  }
}

产生:

  begin
  action!
  end
于 2013-10-19T17:18:54.110 回答