2012-12-08 3 views
2

트랜잭션 블록과 관련된 테이블의 고유 키 제약 조건에 문제가 있습니다.트랜잭션 catch-22

키 제약 조건의 목적은 플레이어가 하나 이상의 목표를 가지지 못하도록하거나 게임 팀 - 기간 - 골키퍼 - 플레이어 당 도움을 피하는 것입니다. 이것은 훌륭하게 작동하며 득점 기록은 중복되지 않습니다.

그러나 팀이 잘못된 goal scorer를 선택하거나 getter를 지원하는 경우 (예 : playerA가 도움을 받았지만 목표에 대한 크레딧을 얻었 음) 레코드를 업데이트하려는 경우 키 제약 조건은 업데이트 시점에 playerA로 발생하는 목표는 동일한 목표에 대한 목표와 지원을 모두 갖게됩니다.

JDBC SQL 래퍼를 사용 중이므로 생성 된 SQL을 직접 제어 할 수 없습니다.

이 문제를 해결하기 위해 기존 목표를 삭제하고 트랜잭션 블록 내에 삽입하기로 결정했습니다. 같은 거래, 핵심 제약 조건을 위반합니다. 동일한 트랜잭션 블록 내에서 삭제하고 삽입 할 수 있습니까? SQL을 생성하는 코드는 무엇인가 같습니다 업데이트를 위해 제출되는 단지 1 팀의 통계의 경우에,

db.handle withSession { implicit ss: SS => 
    ss.withTransaction { 
    val result = for{ 
     d <- teams.map{id=> model.delete(gameID, id)} 
     s <- rows.map{x=> model.insert(x)} 
    } yield s 
    } 
} 
if(result.forall(_.isRight)) Right 
else { ss.rollback; Left(i18n("not updated")) } 

답변

0

이 솔루션은 단일 쿼리에 전체 게임을 삭제했다, 또는 (우리의 시스템에서 허용) , 목표 게임에 대한 해당 팀의 통계를 삭제합니다. 전체 통계의 경우

삭제 우리는이 :

db.handle withSession { implicit ss: SS => 
    ss.withTransaction { 
    val result = for{ 
     d <- model.delete(gameID) 
     s <- rows.map{x=> model.insert(x)} 
    } yield s 
    } 
} 
if(result.forall(_.isRight)) Right 
else { ss.rollback; Left(i18n("not updated")) } 

핵심 비트는 사람이 어디 트랜잭션 블록에서 삭제 된 데이터를 다시 채울 여러 삽입 한 다음 여러 삭제 쿼리를 수행 할 수 없습니다 나타납니다이다 그렇지 않으면 삽입 될 데이터의 삭제가 없어지는 키 제한이 존재합니다.

그 말이 맞는지 또는 그것이 올바른지 확실하지 않은 경우 (;-), 단 하나의 쿼리에서 삭제를 수행하면 그 뒤에 오는 삽입이 문제없이 실행될 수 있습니다.

두 가지 모두에 가장 적합하며 원하는 키 제약 조건을 유지하고 트랜잭션 삭제/삽입을 수행 할 수 있습니다 (참고 : JDBC 래퍼 라이브러리가 지원하지 않으므로 REPLACE INTO을 사용할 수 없음).

+0

문제가 닫힌 것으로 기록되도록 자신의 대답을 수락 할 수 있습니다 .... –