4

시나리오를 고려하십시오. 버전이있는 여러 테이블에서 둘 이상의 행을 envolving하는 Db 트랜잭션.Hibernate (JPA) : 여러 객체가 수정되고 커밋 된 경우 StaleObjectStateException을 처리하는 방법

예 : 상점 목록 및 제품. 숍리스트에는 상품이 포함될 수 있으며 (쇼 프리스트에 금액이 있음) 제품에는 현재 재고가 있습니다.

내가 샵리스트를 편집 할 때 샵리스트에있는 해당 제품의 재고를 재고가 일정하게 유지되도록 업데이트하고 싶습니다.

이렇게하려면 트랜잭션을 열고 쇼핑 목록을 삽입/업데이트하고 각 제품의 재고를 업데이트 한 다음 (델타 적용) 트랜잭션을 커밋합니다. 지금까지는 큰일이 아 닙니다.

그러나 다른 사용자가 하나 이상의 제품을 공통적으로 업데이트했을 수 있습니다. 또는 shopList 자체를 업데이트했습니다. 두 경우 모두 트랜잭션을 커밋 할 때 StaleObjectStateException이 발생합니다.

질문 : StaleObjectStateException을 일으킨 테이블을 확인하는 방법이 있습니까?

제품에서 예외가 발생한 경우 DB에서 모든 envolved 제품을 새로 고친 다음 재고 델타를 다시 적용 할 수 있습니다. 그리고 괜찮습니다. shopList에서 예외가 발생한 경우 문제를 다시보고하여 다시 시작할 수 있도록하는 것이 좋습니다.

도움 주셔서 대단히 감사드립니다.

답변

4

나는 어떻게 발견했다.

우선 대상 : JPA (또는 최대 절전 모드 자체)는 org.hibernate.StaleObjectStateException 예외를 javax.persistence.OptimisticLockException으로 래핑합니다. 그래서 올바른 예외를 잡으려면 OptimisticLockException으로 가십시오.

둘째 : 최대 절전 모드는 EntityManager의 메서드를 호출하기 전에 OptimisticLockException을 throw합니다. 커밋을 직접 호출하면 대신 다른 예외가 발생합니다 (어떤 것을 잊어 버렸습니다). 거의 모든 사람이 commit 메소드가 발행 한 예외를 포착하고 트랜잭션 롤백을 수행한다고 가정하면 롤백 관련 예외가 발생합니다 (어느 것이 다시 한 번 기억이 안나요).

마지막으로 내 원래 질문에 대답 : 버전 오류의 원본을 가져 오려면 OptimisticLockException 인스턴스에서 getEntity 메서드를 호출하기 만하면됩니다. 그것은 당신이 당신과 관련된 모든 것을 제공 할 것입니다.

여기를 통과 한 모든 사람들에게 감사드립니다. 그 점에 관해 궁금한 점이 있으시면 언제든지 문의하십시오. 기꺼이 도와 드리겠습니다.

+1

session.flush가 호출 될 때만 예외가 발생하는 전체 표시입니다. 호출되지 않으면 RollbackException으로 반환됩니다. 이 예외에서는 아무 것도 할 수 없습니다. 당신은 그것에 어떤 정보든지를위한 질의를 기울인다, 아무 정보도 보유하지 않기 원인을 일으키는 원인이된다. 당신은 플러시 전화 확인하십시오. – sethu