2012-07-04 2 views
1

우리는 tomcat 7과 MySQL 5.5에서 실행되는 대규모 엔터프라이즈 애플리케이션을 위해 JPA 2와 Spring 3.0.5에서 Hibernate 3.6.0.Final을 사용하고 있습니다. 응용 프로그램의 대부분의 트랜잭션은 1 초 미만으로 유지되며 5-10 개 엔티티를 업데이트하지만 일부 사용 사례에서는 단일 트랜잭션으로 10-20,000 개 이상의 엔티티를 업데이트해야하므로 몇 분이 걸리므로 시간의 70 % 이상이 소요됩니다 그러한 엔티티의 일부가 다른 트랜잭션에 의해 갱신 되었기 때문에 이러한 트랜잭션은 StaleObjectStateException으로 실패합니다.트랜잭션이 수천 개의 엔티티를 업데이트 할 때 StaleObjectStateException을 피하는 방법은 무엇입니까?

우리는 일반적으로 모든 테이블에 버전 열을 유지하며 StaleObjectStateException의 경우 일반적으로 재 시도하지만 이러한 longs 트랜잭션은 어쨌든 매우 길기 때문에 재 시도를 계속하면 탈출 할 수 있을지 잘 모르겠습니다 StaleObjectStateException.

많은 활동으로 바쁜 시간에 이러한 항목을 계속 업데이트하므로 시스템에서 많은 활동을 잠재적으로 중단시킬 수 있으므로 비관적 인 접근 방식을 사용할 수 없습니다.

일부 성공적인 거래가 실패한 경우에 대비하여 데이터를 엉망으로 만들 수 없기 때문에 수천 개의 독립적이고 작은 거래를 생성 할 수 없으므로 이러한 긴 거래 문제를 해결하는 방법을 제안하십시오.

+1

바쁜 시간 이외에 이러한 사용 사례를 실행 하시겠습니까? –

+0

이것이 가능하다면 좋겠지 만, 실제로 이러한 응용 프로그램은 업무 시간 중에 많이 사용되며이 응용 프로그램은 해당 시간에만 작동합니다. 우리가이로드를 처리 할 수 ​​없기 때문에 밤늦게까지 작업하도록 요청하면 엔지니어링 팀에게 수치스러워 할 것입니다. – ThinkFloyd

답변

1

하나의 트랜잭션에서 20,000 개의 엔티티를 수정하는 것이 실제로 많은 일이며, 이는 정상적인 것보다 훨씬 더 중요합니다.

나는 일반적인 해결책을 줄 수는 없지만 여기에 문제를 해결하는 방법이 있습니다.

1) LockMode.UPGRADE을 사용하십시오 (pessimistic locking 참조). 여기서 명시 적으로 "SELECT FOR UPDATE"를 생성하여 다른 사용자가 잠긴 동안 행을 수정하지 못하도록합니다. 이렇게하면 문제가 발생하지 않지만 큰 트랜잭션이 너무 많으면 프로그래밍에 따라 교착 상태가 발생하거나 시간이 초과 될 수 있습니다.

2) 이러한 대규모 트랜잭션을 피하기 위해 데이터 모델을 변경하십시오. 왜 10,000 개의 행을 업데이트해야합니까? 아마도 많은 행에 업데이트 된이 정보를 새 테이블에 넣고 참조 만 할 수 있으므로 새 테이블에서 몇 행만 업데이트해야합니다.

3) Session 대신 StatelessSession을 사용하십시오. 이 경우에는 예외 이후에 롤백 할 필요가 없으며 대신 문제를 해결하고 계속 진행할 수 있습니다 (이 경우 수정 된 엔티티를 다시로드하고 다시로드 된 엔티티에서 큰 트랜잭션에 대한 수정 작업 수행). 이것은 아마 당신에게 중요한 이벤트 (행이 수정되는 동안)를 처리 할 수있는 가능성을 제공합니다.

관련 문제