Hibernate 값 형식 집합 을 사용 하여 발생 하 는 병발 문제 와 해결 방법

2447 단어 HibernateF#
Hibernate 의 값 유형 집합 은 사용 하기에 편리 하지만 최근 사용 에서 병발 문제 가 발견 되 었 습 니 다.다음 과 같다.
지구 화 클래스 A 는 n 개의 질서 있 는 long 형 수 를 포함해 야 합 니 다.클래스 A 는 데이터베이스 에 저장 해 야 합 니 다.
클래스 A 는 다음 과 같 습 니 다.
public class Foo{

    // some properties

    List longNumbers=new ArrayList();


    // some propertes' getter and setter


  public  List getLongNumbers(){

      return this.longNumbers;

  }


 public void setLongNumber(List longNubmers){

     this.longNumbers=longNumbers;

  }


}


값 집합 에 대응 하 는 hibenate 설정 만 다음 과 같 습 니 다.
<list
            name="longNumbers"
            table="itil_foolongnumbers"
            lazy="false"
            inverse="false"
            cascade="all-delete-orphan"
        >

              <key
                  column="ifooid"
              >
              </key>

              <index
                  column="iindex"
              />

              <element
                  column="ilongnumber"
                  type="java.lang.Long"
                  not-null="false"
                  unique="false"
              />
        </list>

설정 이 완료 되면 foo 대상 에 log 형의 값 을 직접 추가 하고 hibenate 의 Session 을 통 해 추가 삭제 검 사 를 할 수 있 습 니 다.
그런데 문제 가 생 겼 어 요.두 개 이상 의 스 레 드 가 다음 코드 를 동시에 실행 할 때 오류 가 발생 합 니 다.(코드 는 의미 만 표시 하 는 것 이 엄격 하지 않다)

public void appdendLongNumber(Long fooId,Long num){
     Transaction tr=session.beginTransaction();
     Foo f=session.get(fooId,Foo.class);
     f.getLongNumbers().add(num);
     tr.commit();
     ...
}

발생 한 오 류 는 hibenate 가 잘못 보고 한 것 이 아니 라 데이터베이스 메 인 키 충돌 이상 입 니 다.
분석 결과: 원래 itilfoolongmnumbers 표 는 ifooid 와 iindex 를 복합 키 로 합 니 다.두 개의 스 레 드 가 동시에 OID 와 같은 Foo 대상 에 게 새로운 Long Number 를 추가 할 때 두 스 레 드 에 있 는 Foo 대상 은 각각 같은 아래 표 시 된 Long Number 요 소 를 가지 게 됩 니 다.그 다음 에 먼저 저 장 된 Foo 대상 이 성공 하고 두 번 째 로 데이터베이스 에 저 장 된 경우 메 인 키 가 충돌 합 니 다.
이 문 제 는 개발 할 때 생각 하기 어렵다.
이 문 제 는 다음 과 같은 방식 으로 해결 할 수 있다.
두 가지 방법:
1. 코드 급 상호 배척.
2. 다시 시도 한다.

좋은 웹페이지 즐겨찾기