进行数据库交易:
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) }
)
}
}
}
如果存储库用户创建实现采用隐式会话,是与上面启用了withTransaction的会话相同的会话,还是隐式值“是”而不是“是”身份?< / p>
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
我可以明确地传递Session repo.user.create(model)(ss)
并创建一个明确的Session,但我很想知道更简洁/方便的隐式方法是否提供了相同的结果, 事务已启用会话。
答案 0 :(得分:1)
如果我正确地理解了您,您正在使用ScalaQuery,并且您希望在用户从外部提供会话时也能使用您的方法。
def withSession [T](f:⇒T):T用新会话运行提供的thunk和 最后自动关闭会话。
def withSession [T](f: (会话)⇒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)
}
答案 1 :(得分: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)
的{{1}}转发至M1.create
编译器显然忽略了其他隐式存储M2.create
。