0

进行数据库事务:

def create(model: Model, orderNum: String) = {
  db.handle withSession { implicit ss: Session=>
    ss.withTransaction { // auto commit now set to false
      val result = for {
        uid <- repo.user.create(model)
        mid <- repo.membership.create(uid)
        oid <- repo.orders.create(model, uid, orderNum)
      } yield uid
      result fold( 
        e=> { ss.rollback; Left(e) }, 
        s=> { Cache.remove("member.directory"); Right(s) } 
      )
    }
  } 
}

如果存储库用户创建实现采用隐式 Session,它是否与上面启用了 withTransaction 的 Session 相同,或者是隐式值“is a”而不是“is the”身份?

def create[T <: User](t: T)(implicit ss: Session) = // what Session is this?
  for {
    uid <- either( Users.insert( Users(t) ), i18n("user not created") )
    ur  <- either( UserRoles.insert( UserRole(uid, t.role) ), i18n("user role not created") )
  } yield uid

我可以显式传入会话repo.user.create(model)(ss)并创建显式会话,但我很想知道更简洁/方便的隐式方法是否提供相同的结果,启用事务的会话。

4

2 回答 2

1

如果我正确理解您,您正在使用 ScalaQuery,并且您希望您的方法在用户从外部提供会话时也能正常工作。

def withSession [T] (f: ⇒ T): T 使用新会话运行提供的 thunk 并在结束时自动关闭会话。

def withSession [T] (f: (Session) ⇒ T): T 使用新会话运行提供的函数并在结束时自动关闭会话。

这两个都在创建一个新事务,所以我会采用 Optional[Session] 作为隐式并将其默认为 None

  def onProvidedOrCreatedSession[K](f: Session => K)(session:Option[Session]) = {
    session match {
      case Some(s) => f(s)
      case None => db.withSession { f }
    }
  }

  def create(model: Model, orderNum: String)(implicit session:Option[Session]=None){
    onProvidedOrCreatedSession( 
      implicit s => s.withTransaction {  val x = 10 }
    )(session)  
     
  }
于 2012-08-03T15:12:01.357 回答
0

不确定以下是否是您尝试做的忠实抽象,但我希望它有所帮助:

class Store(var x: Int) {
  def flip() { x = -x }
}

object M1 {
  implicit val store2 = new Store(2)

  def create(s: String) = {
    implicit val store3 = new Store(3)

    { implicit store: Store => 
        println("[M1.create] store.x = " + store.x)
        store.flip()
        M2.create("tummy")
        println("[M1.create] store.x = " + store.x)
    }
  }
}

object M2 {
  implicit val store4 = new Store(4)

  def create(s: String)(implicit store: Store) = {
    println("[M2.create] store.x = " + store.x)
    store.flip()
  }
}

M1.create("dummy")(new Store(1))

输出是:

[M1.create] store.x = 1
[M2.create] store.x = -1
[M1.create] store.x = 1
  • new Store(1)明确传递给的M1.create转发给M2.create

  • store2, store3, store4编译器显然忽略了附加的隐式存储。

于 2012-08-03T13:25:51.630 回答