2014-09-29 6 views
1

나는 Hibernate에서 영구적 인 hibernate managed @entity Obj를 가지고 있는데, 이는 id, fieldA, fieldB 필드를 포함한다.HibernateOptimisticLockingFailureException을 피할 수있는 방법이 있습니까?

일부 클래스에는 updateA() 및 updateB()라는 두 가지 트랜잭션 메소드가 있습니다.
updateA()는 ID로 Obj를 얻고 처리하고 fieldA를 업데이트합니다.
updateB는 fieldB와 동일합니다.

또한 지속적으로 요청하는 두 개의 클라이언트가 있습니다. 한 클라이언트는 항상 updateA()를 호출하는 요청을 만들고 다른 클라이언트는 항상 updateB()를 호출합니다.
둘 다 기존 Obj의 동일한 ID를 전달합니다.

HibernateOptimisticLockingFailureException이 발생하지 않거나, 각 메소드가 다른 필드를 업데이트한다는 사실을 고려하여 성공적으로 처리하면 HibernateOptimisticLockingFailureException을 피할 수있는 방법이 있습니까? 병합 같은 거?

updateA()를 호출하는 스레드는 실제로 updateA()와 비슷한 다른 트랜잭션 방식을 호출하지만 아무 것도 fieldB를 업데이트하지 않습니다.

처음에는 예외를 catch하고 두 번째 작업을 다시 시도했습니다. 하지만 때로는 두 번째로 실패하는 경우도 있습니다 ... 좋은 해결책이 아닌 것 같습니다. 당신이 안전하게 할 수 있다면

+0

것은 당신이 버전을 사용하고을 ('Version' @) 귀하 실재? –

+0

@Version을 사용하지 않습니다. 그것에 대해 읽을 것입니다 – inor

답변

1

, 가장 쉬운 방법은 낙관적 잠금에서 fieldB을 제외하는 것입니다 :

import org.hibernate.annotations.OptimisticLock; 

/* ... */ 

@OptimisticLock(excluded=true) 
private B fieldB; 
+0

두 클라이언트가 동시에 fieldB를 업데이트하면 실패하지 않을까요? –

+0

@ThomasStets는 어떤면에서 실패합니까? –

+0

좋아요, 저는 그가 필드 B를 업데이트하는 클라이언트가 하나 밖에 없다는 사실을 놓쳤습니다. 그러나, 더 많은 클라이언트들이 있다면, Hibernate가 알아 차리지 않고 다른 하나로부터 업데이트를 덮어 쓸 수 있습니다. –

1

당신은 automatic optimistic locking retry mechanism를 사용할 수 있습니다.

<dependency> 
    <groupId>com.vladmihalcea</groupId> 
    <artifactId>db-util</artifactId> 
    <version>0.0.1</version> 
</dependency> 

가 그럼 그냥 다음 주석과 서비스 방법을 표시 : 다음 종속성을 추가 할 필요가 들어

@Retry(times = 5, on = OptimisticLockException.class) 
관련 문제