2014-05-11 4 views
2

당신이 "자동 거래"에 의존하고있었습니다 경우장고 1.5 select_for_update는 깨지기 쉬운 디자인

이 select_for_update() 및 후속 쓰기 작업 사이 잠금 제공하는 Django documentation 상태로 간주 - 관련 코드를 atomic()로 묶어야합니다. Django 1.6.3부터 자동 커밋 모드에서 select_for_update()를 사용하여 쿼리를 실행하면 TransactionManagementError가 발생합니다.

왜 연약한가? 나는 이것이 적절한 거래 성을 가져올 것이라고 생각했을 것이다.

답변

3

Aymeric은 Django 1.5의 암시 적 트랜잭션에 의해 형성된 암시 적 트랜잭션 경계에 의존하기 때문에 그러한 디자인이 깨지기 쉽다고 전자 메일을 통해 명확하게 설명했습니다.

select_for_update(...) 
more_code() 
save() 

이 코드는 간단 경우에 작동하지만, 데이터베이스에 대한 쓰기 작업에 more_code() 결과, 다음 트랜잭션이 종료 할 경우, 의도하지 않은 동작을 생산.

사용자가 트랜잭션 경계를 지정하도록 강요하면 코드가 명확 해집니다.

3

대답은 select_for_update (강조 광산)에 대한 문서에 임박 :

행이 다음 잠기지 않은 때문에 오류 자동 커밋 모드에서 select_for_update와의 검색어입니다 평가. 허용되는 경우 은 데이터 손상을 촉진하고을 호출하며 트랜잭션 외부에서 을 호출하면 쉽게 손상 될 수 있습니다. 코드는 하나에서 실행될 것으로 예상됩니다.

즉, 데이터 손상을 초래할 수있는 autocommitselect_for_update 사이에 상충하는 동작이 있습니다. 그들이 첫 번째 (다시 강조 광산)를 인용,이 문제를 해결 제안 곳 여기 django developer's discussion입니다 :

[...] 오라클에서 자동 커밋 모드에서 자동 커밋 명령이 실행 된 직후 를 발생 - - 따라서 을 가져 오려고하면 별도의 트랜잭션에서 결과가 실패합니다.

그러나 임의의 백엔드가있는 , 자동 커밋 모드의 select-for-update 은 거의 의미가 없습니다. 심지어 파손되지 않더라도 (오라클 에서처럼) 실제로 아무 것도 잠그지 않습니다. 따라서 자동 커밋 모드에서 업데이트 선택 인 쿼리를 실행하는 IMO는 아마도 오류 일 수 있으며 데이터 손상 버그를 일으킬 수있는 오류 일 수 있습니다.

그래서 우리는 select-for-update 쿼리의 동작을 바꿔 줄 것을 제안합니다. [...] 이것은 이전 버전과 호환되지 않는 변경입니다. [...] 이러한 프로젝트는 아마 감사해야합니다 - - 그들은 지금 노출되어있는 미묘한 버그로 달리고있었습니다.

그래서 오라클 전용 버그로, 모든 백엔드와 관련된 더 깊은 문제에 대한 조명을 보여 주었고, 따라서 장고에서 오류가 발생하도록 결정했습니다.

Atomic은 오류가 없는지 확인한 후에 만 ​​데이터베이스에 커밋하므로 문제가 해결됩니다.

+0

작성한 것은 의미가 있지만 문서가 작성된 방식에 따라 설계가 1.5에서 취약하다는 것을 나타냅니다. "당신이 *"자동 트랜잭션 "에 의존했다면 .... .... 내게 이것은 select_for_update를 1.5로 사용하여 업데이트를 위해 행을 고정시키는 것은 데이터베이스 자동 커밋을 사용하지 않아도 깨지기 쉬운 디자인이라고 말합니다 (그러나 장고의 ' autocommit 'application implementation) – Taras

+0

예, 맞습니다. 자동 커밋을 사용할 때만 깨지기 쉽습니다. ** 실제로 ** 아무것도 잠그지 않기 때문에 그렇게 간주됩니다. 그것은 일반적인 의미에서 허약하지 않습니다. 그리고 notice -이 오류는이 문제를 다루고 있습니다. 왜냐하면 단지'select_for_update' 사용법 *에서 * autocommit을 사용했을 때만 활성화 되었기 때문에 모두 의미가 있습니다. – yuvi

+0

Django 1.6+에만 적용되는 '극도로 취약한 디자인'주석이 있습니까? 문서가 쓰여진 방식은 Django <1.6의 경우 select_for_update가 약한 것으로 간주 됨 – Taras

9

select_for_update은 깨지지 않습니다.

필자는 ""자동 ​​트랜잭션 "을 사용하는 경우 1.6에서 1.5로 업그레이드 할 때 코드를 검토해야한다고 썼습니다.

"자동 트랜잭션"에 의존하지 않고 개념이 종을 울리지 않으면 더 많은 작업을 수행 할 필요가 없습니다.

yuvi 님의 답변 (아주 좋았습니다. 고맙습니다!) 장고는 잘못된 코드를 만나면 예외를 발생시킵니다. select_for_update이 제기 된 TransactionManagementError이 나올 때까지 생각할 필요가 없습니다.

+2

장고 프레임 워크의 핵심 개발자 인 * fiesta *의 첫 번째 게시물! 기고에 감사드립니다. 희망이 당신에게서 다른 포스트를 앞으로는있을 것이다 :-) –