2012-10-19 4 views
1

나는 customer.In에 대한 정보가 들어있는 customer라는 이름의 최대 절전 모드 엔티티가 있습니다. 나는 고객 정보를 데이터베이스에 삽입해야하는 parametres로 가져 왔습니다. 그래서 중복 된 항목을 제거하려면 해당 고객이 이미 db에 있는지 여부를 확인해야합니다. 그러나 문제는 두 번의 호출이 같은 고객 정보를 가진 한 순간에 같은 메소드로 호출되면 제약 조건 위반 오류가 발생한다는 것입니다. 나는 saveOrupdate()가 문제를 해결할 것이라고 생각했지만 hasnt는 아니다. 누군가이 시나리오에 대한 해결책을 제시 할 수 있습니까?SaveOrUpdate 동안 고유 제약 조건 위반 오류

답변

3

saveOrUpdate는 완전히 다른 목적으로 사용됩니다. 그것은 이미 영속성이있는 (id와 all을 가짐) 엔티티를 지속시키기위한 것이거나 새로운 id 일 수 있습니다. 동시 액세스 권한은 없습니다.

문제점으로는 낙관적 잠금 및 비관적 잠금이라는 두 가지 옵션이 있습니다.

비관적 잠금 : 고객이 있는지 여부를 확인하기 전에 잠금을 생성하여 현재 스레드 만 계속 진행할 수 있습니다. 따라서 검사가 수행되고 그에 따라 작동합니다. 동일한 데이터를 가진 다른 스레드는 첫 번째 스레드의 업데이트 또는 삽입이 완료 될 때까지 기다려야합니다. 잠금은 단일 컴퓨터에서 실행되는 경우 최대 절전 모드 또는 단순히 동기화 된 블록을 사용하여 데이터베이스에 구현 될 수 있습니다.

낙관적 잠금 : 바로 지금 당신처럼 진행하십시오. 하지만 질문에 설명 된 충돌 사례를 처리하기 위해 예외 처리기를 배치해야합니다.

동기 잠금은 동기화 된 블록을 사용하여 구현하는 것이 더 쉽지만 성능과 확장성에 큰 영향을 미칩니다.

+0

잘 동기화 된 메서드를 만들려고했지만 여전히 오류가 지속하는 데 도움이되지 않았습니다. 동기화 된 메서드로 스레드를 안전하게 만들 수 있습니다. ?? – Naman

+0

아니요, 변경 가능한 모든 정보가 동일한 모니터를 사용하는 동기화 된 블록에서만 액세스 될 때 스레드 안전성을 얻습니다. 간단하지 않은 코드가 스레드로부터 안전한지 결정하는 것은 쉽지 않습니다. –

+0

안녕하세요 jens 한 번 더 의심! f1과 f2라는 두 가지 기능이있는 시나리오가 있습니다. 함수 f2가 f1에 의해 호출되고 f2가 동기화됩니다. 따라서 함수 f1에 대한 동시 호출이 함수 f2가 동기화되는 것에 대해 신경 쓰지 않는다면 당신에게 따르면 ?? – Naman

0

saveOrUpdate은 객체 의 기본 키 속성 값에서 작동합니다. 0이 새 개체의 기본값이고 새로운 customer 개체의 기본 키 특성이 0으로 설정되어 있으면 항상 저장 (삽입)을 시도하고 업데이트하지 않습니다. 기본 키 속성이 0이 아닌 값일 때만 업데이트를 시도합니다. 이것이 saveOrUpdate이 문제를 해결하지 못하는 이유입니다.

나는 당신이 주변에 작품으로 unique 제한 예외를 처리하는 것보다 더 나은 무엇을 할 수 있는지 모르겠습니다.

+0

이 데이터베이스 작업이 발생하는 동기화 된 방법으로 문제를 해결할 수 있습니까 ?? 한 번에 하나의 스레드 만 허용해야합니다! – Naman

+0

메소드 자체에서 두 번째 고객 오브젝트가 중복 체크 로직에 의해 정상적으로 필터링되므로 중복 여부를 확인하므로 '예'입니다. 일반적으로 우리는 그러한 검사를하지 않으며,이 경우 두 번째 호출은 여전히 ​​실패합니다. –

관련 문제