我在调试事务查询块时碰到了这个头颅。
出于某种原因,尽管折叠左/失败操作中发生了连接回滚,但成功/正确的结果也会被回滚。
示例:
// returns Either[String, Int]
db.handle withSession { implicit ss: Session=>
ss.withTransaction {
val result = for {
u <- either(User.insert(User(model)), ss)
ur <- either(UserRole.insert( UserRole(u) ), ss)
m <- either(Membership.insert(Membership(u)), ss)
} yield u
// bad: rollback occurs regardless of left/right outcome
result fold( {ss.rollback; Left(_)}, Right(_) )
// good: rollback occurs as expected on left outcome only
result fold( e=>{ss.rollback; Left(e)}, Right(_) )
答案 0 :(得分:4)
考虑以下稍微简单的例子:
def foo[A, B](e: Either[A, B]) = e.fold(
{ println("Launch the missiles!"); Left(_) },
Right(_)
)
每次调用foo
时,导弹都会启动,因为我们传递的第一个参数并不完全是一个函数:它是一个计算函数的块,并且该块将被评估是否使用该功能。
请参阅Jesse Eichar的this blog post,了解有关此行为的更详细讨论。