2011-03-01 2 views
1

나는 GeneralKnowledgeTest 객체를 가지고 있으며 사용자가 그 테스트를 할 때마다 업데이트되는 많은 통계 필드 (ratingsCount, responsesCount, ratingStars ...)를 포함하고있다. takeTest() -> 트랜잭션 메소드).spring/jpa/hibernate에서 낙관적 잠금에 관한 간단한 디자인 질문

동시에 많은 사용자가 동일한 테스트를 수행 할 수 있으므로 낙관적 잠금 예외가 throw되는 경우 takeTest 메서드를 다시 시도하는 낙관적 잠금 (@version) 및 a 인터셉터를 구현할 생각이었습니다. .

따라서 takeTest 메서드 내에서 항상 새로운 GeneralKnowledgeTest 인스턴스를 얻습니다. entityManager.find (testId) 그런 다음 통계 필드를 업데이트하십시오. 낙관적 인 예외가 발생하는 경우 인터셉터는 성공할 때까지 단순히 takeTest 메서드를 다시 시도합니다.

이 절차에 대한 의견이 있으십니까? 동일한 테스트를 수행하려고하는 사용자가 많은 시스템에 대해 낙관적 잠금을 구현하는 좋은 방법입니까?

추신. 비즈니스는 낙관적 인 잠금 예외가 발생하면 경고 메시지를 표시하지 않습니다. 따라서 인터셉터는 원활한 실행을 위해 반드시 필요합니다 ...

답변

0

이 통계는 테스트가 끝난 후에 만 ​​업데이트되고 있다고 가정합니다. 테스트를 실행하는 데는 상당한 시간이 걸리므로 낙관적 인 잠금 실패의 가능성이 줄어 듭니다. 또한 설정된 시간에 테스트를 시작한 결과 사용자가 버스트로 테스트를 완료 할 가능성이 있습니까? 이렇게하면 잠금 실패 가능성이 높아집니다.

처리량이 동시 업데이트의 가능성이 높으면 스레드의 안전한 방식으로 메모리에 통계를 집계하고 주기적으로 데이터베이스에 쓰는 것이 좋습니다.

+0

많은 사용자가 동일한 시간에 테스트를 수행하고 완료 할 수 있습니다 (예 : 하루 테스트 등). 나는 낙관적 인 잠금 성능 측면에서 괜찮아요 읽어, 그래서 데이터베이스 잠금이 없습니다. (100 명의 사용자가 동일한 시간에 동일한 테스트를 수행/완료하고 takeTest가 트랜잭션을 조금 더 오래 걸리게하는 많은 추가 db 객체를 만드는 복잡한 메소드라고 생각해보십시오). 그러나 일반적으로 내가 제안한 approch에 문제가 있습니까? 오류나 불일치가 있습니까? 사전에 감사합니다 –

+0

아니오, 오류가 없습니다. 낙관적 인 잠금 기능을 사용하지 않으면 데이터를 다시 읽게되지만 데이터베이스로드가 증가하고 테이크 테스트 로직을 다시 실행하면 CPU로드가 증가합니다. 이 접근법에는 아무런 문제가 없으며 잠금 실패 빈도에 따라 달라집니다. – Will

0

이 유효한 방식처럼 들린다 동시 변경이 검출되는 경우에 예외를 발생 플러시시

절전 인스턴스 버전들을 체크. 이 예외를 잡아서 처리하는 것은 개발자에게 달려 있습니다. 일반적인 옵션은 사용자가 변경 사항을 병합하거나 오래된 컨텐트가 아닌 비즈니스 대화를 다시 시작할 수있는 기회입니다.

또한 IsolationLevel을 SERIALIZED로 설정하거나 테이블 행을 잠그는 방법을 살펴볼 수도 있습니다.

또 다른 옵션은 개체를 분리하고 통계가 업데이트되도록 업데이트 한 다음 스케줄러 등을 사용하여 개체를 다시 첨부 (업데이트) 할 수 있습니다. 그러나 이것은 서비스 방법 (업데이트 통계)이 동기화되도록 요구할 수 있으며이 서비스는 아마 프록시가 가능하기 때문에 동기화가 가능하다고 생각하지는 않습니다.

관련 문제