2011-03-01 4 views
0

재시도 인터셉터를 사용하여 기본적인 낙관적 잠금 메커니즘을 구현하려고합니다.jpa/spring/hibernate에서 간단한 낙관적 인 잠금 질문

속성은 respondCount 속성을 가진 객체 퀴즈입니다. 퀴즈를 업데이트하는 동안 낙관적 인 Lock 예외가 발생하면 각각의 업데이트 메소드가 재시도 인터셉터에서 다시 호출됩니다.

재 시도 된 메소드가 매번 동일한 버전 번호를 가지기 때문에 무언가가 올바르지 않은 것이고, 그 이유는 무엇이든지 상관없이 트랜잭션을 실패하게 만듭니다.

버전 10

공정 A : 업데이트 시작 퀴즈 버전 10 개 공정 B : 업데이트 시작 퀴즈 버전 10 공정 B : 마무리 업데이트 퀴즈 버전 11 공정 A : 낙관적 예외 던져진 업데이트 퀴즈, 다시 시도 A 프로세스 재 시도 된 메서드 내 버전은 항상 10

어떻게해야합니까? 트랜잭션을 성공시키기 위해 버전을 자동으로 증가시켜야합니다.

답변

1

낙관적 잠금 예외는 다음과 같이 처리됩니다

먼저 새 버전 번호와 충돌하는 트랜잭션이 쓴 업데이트 된 필드 값을 받고, 기록을 다시 읽어보십시오.

그런 다음 새 값에 따라 작업을 다시 적용하십시오. 당신의 경우에 이것은 간단합니다 - 값을 증가시키는 것은 순서 독립적이거나 교환 가능합니다. 다른 작업은 다시 적용하기가 쉽지 않을 수 있습니다. 예를 들어, 트랜잭션이 모두 워크 플로우 상태에서 다른 워크 플로우 상태로 버그를 이슈 추적기로 이동하려는 경우를 가정합니다. 이 전환은 한 번만 발생할 수 있으므로 다시 시도하는 트랜잭션은 버그가 해당 전환에 대해 유효한 상태에 있는지 확인해야하며 그렇지 않은 경우 사용자에게 오류를보고합니다.

0

낙관적 인 잠금 장치를 물리 치려고합니다. D : 낙관적 인 잠금 장치가 필요합니까?

이전 데이터를 잃지 않고 다시 시도하는 유일한 방법은 개체를 새로 고친 다음 변경 사항을 다시 적용하는 것입니다. 어떤 식 으로든 데이터를 재정의하면 아이디어에 어긋납니다. 낙관적 인 자물쇠.

귀하의 경우, 낙관적 잠금을 사용하지 않거나 낙천적 잠금을 사용하지 않고 보조 테이블에 계산을 넣을 것입니다.

+0

수를 잠글 필요가 있습니다. 그렇지 않으면 두 클라이언트가 '1'을 읽은 다음 올바른 수가 '3'일 때 '2'를 쓰게됩니다. – tgdavies

1

누군가 다른 사람이 등 뒤에서 (낙천적 예외를 던집니다.) 업데이트 한 경우에도 퀴즈를 업데이트하고 싶습니다. 그렇다면이 엔티티에서 낙관적 인 로깅을 사용하는 이유는 무엇입니까? 버전 필드를 제거하면 다시 시도하지 않고도 작동합니다.

실제로 버전 필드를 유지하려면 DB에서 퀴즈를 가져오고 새로로드 된 퀴즈의 버전 번호를 분리 된 인스턴스에 복사 한 다음 분리 된 인스턴스를 병합하여 모두 복사하십시오 새로운 값이 첨부 된 값.

+0

낙관적 잠금을 사용하려고 생각하는 이유는 많은 동시 사용자가 퀴즈를 가져 와서 같은 시간에 퀴즈의 quizResponsesCount 속성을 증가시키는 경우를 방지하는 것입니다. 지금 당장 당신이 제안한 것을 실험하고 있습니다. db에서 새로운 객체 (퀴즈) 만 가져오고 업데이트하는 방식으로 서비스 레이어를 수정했습니다. 필자가 테스트 한 바에 따르면 재시도 메커니즘이 이러한 방식으로 잘 작동한다는 것을 의미합니다. 즉, 낙관적 인 잠금을 감지 한 다음 메서드를 다시 시도하고 다음에 성공할 것입니다. 이런 식으로 괜찮습니까? –

관련 문제