3

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を学んでおり、アプローチを改善するためのアドバイスを探しています. より良い結果を得るために、何らかの方法で関数を変更できますか? または、別のユニット タイプ固有の機能を追加しますか? それとも別の道を選ぶ?

何か案は?これを実装するための標準的な方法はありますか? ありがとう。

4

2 に答える 2

3

メソッドtxは1引数の関数をパラメーターとして受け入れ、メソッドsaveMyEntityは引数を受け入れないため、(1引数の関数)として使用することはできませんA => B

aと を別々に使用していないfため、 は必要ありませんaここでは、名前別パラメーターを使用できます。

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

saveMyEntityasを使用するUnit => 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 に答える