2012-07-06 4 views
1

트랜잭션 쿼리 블록을 디버깅하는 동안이 헤드 스크래쳐를 만났습니다.이상한 폴드 스코핑 문제

어떤 이유인지, fold left/fail 조작에서 연결 롤백이 발생 했음에도 불구하고 성공/올바른 결과가 롤백되고있었습니다.

예 :

// 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(_)) 

답변

4

다음 약간 간단한 예를 생각해

미사일은 우리가 전달하는 첫 번째 인수가 없기 때문에, 당신은 foo를 호출 할 때마다 시작받을 예정
def foo[A, B](e: Either[A, B]) = e.fold(
    { println("Launch the missiles!"); Left(_) }, 
    Right(_) 
) 

정확히 함수 : 함수로 평가되는 블록이며 함수가 사용되는지 여부를 평가하게됩니다.

이 동작에 대한 자세한 설명은 Jesse Eichar가 this blog post을 참조하십시오.

+0

+1 정말로, 미사일이 발사 될뿐만 아니라 화가 난 고객의 현대 미사일도 보내질 것입니다 .- 나는 최소한의 말로 복잡하게 전개되었지만 이제는 폴드 블록의 매개 화가 필수적입니다. 실마리를 가져 주셔서 감사합니다 ... – virtualeyes