2017-12-02 27 views
1

최대 절전 모드에서 READ COMMITED 및 READ UNCOMMITED 분리 수준이 작동하는 방식을 이해하고 몇 가지 설명이 필요하다.Hibernate에서 공유 잠금과 배타 잠금을 획득하는 방법

동일한 트랜잭션 실행 방법 2 개 스레드 에서 Thr1 및 Thr2에서 모두 (봄 커밋 읽기 전용으로 설정 분리 레벨 Transactional 주석)가있다. 생성 된 이름 트랜잭션은 TRA1TRA2 이에 따라 생성됩니다. 다음과 같이 트랜잭션 방법은 같습니다

public void updateOrSavePreference(String name, String value) { 
    Preference preferenceToUpdate = findPreferenceUsingNamedQuery(name); // line 1. shared read lock acquired (uses HibernateTemplate.findByNamedQueryAndNamedParam(...)) 
    if (preferenceToUpdate != null) { // line 2. 
    preferenceToUpdate.setValue(value); // line 3. exclusive write lock acquired (actually I use the HibernateTemplate.merge(...) method 
             // instead a setter because the entity type is immutable, but it seems irrelevant for this example) 
    } else { // line 4. 
    HibernateTemplate.save(preferenceToUpdate); // line 5. exclusive write lock acquired 
    } 
} 

환경 설정 클래스는이 엔티티에 대한 2PL 모델을 적용 할 Entity (optimisticLock = OptimisticLockType.NONE)의 주석을 붙일 수 있고 (내가 잘못?). Oracle 데이터베이스를 사용합니다.

는 다음과 같은 시나리오를 생각해

  1. 이의 그 스레드 1를 줄 수에서 Thr1 단계를 가정하자 객체를 쿼리합니다. 내가 올바르게 이해하면,이 스레드에 의해 생성 된 트랜잭션 TRA1은 쿼리 된 엔티 리에 대한 공유 읽기 잠금을 획득합니다. 그런 다음 THR2 쓰레드가 라인 3에서이 엔티티에 대한 배타적 쓰기 잠금을 획득하려고하면 TRA1이 읽기 잠금을 해제 할 때까지 THR2를 차단해서는 안됩니까?

  2. 스레드 THR1이 3 행에서 엔티티에 대한 독점 쓰기 잠금을 획득한다고 가정 해 봅니다 (독점 잠금은 TRA1 transaction completes까지 유지됩니다). 그런 다음 THR2 스레드는 1 행으로 이동하여이 엔티티를 쿼리합니다. 다른 트랜잭션 TRA1이이 엔티티에 대해 독점 쓰기 잠금을 보유하고있는 동안 TRA2 트랜잭션이 읽기 잠금을 획득하려고하기 때문에 THR2를 차단해서는 안됩니까?

  3. READ UNCOMMITED 격리 수준에 대해 2 번에서 시나리오를 재생하면 TRA2 트랜잭션을 실행하는 THR2는 refreshing 이후에도 TRA1 트랜잭션의 THR1 변경 내용을 보거나 엔티티를 다시 쿼리합니다 ("평가 식" 디버그 중). 왜?

답변

1

기술적으로 읽기 커밋은 읽기 잠금을 설정하여 수행 할 수 있습니다. 그러나 반드시 그런 것은 아닙니다. DBMS가 MVCC를 지원하면 자물쇠를 설정하지 않고 커밋 된 데이터를 읽습니다 (자체 트랜잭션에서 변경된 내용 제외).

오라클, mysql (INNODB) 또는 포스트그레스를 사용하여 테스트를 수행 한 것으로 의심됩니다. 이러한 모든 DBMS는 기본적으로 MVCC를 지원하므로 공유 읽기 잠금을 설정하지 않습니다.

오라클 "MVCC"데이터베이스를 사용하기 때문에 엔티티에서 구성하더라도 2PL 프로토콜이 구현되지 않습니다.

<property name="hibernate.show_sql" value="true" /> 

은 아마 당신도 transaction-isolation-levels-relation-with-locks-on-table을 살펴해야한다 : 당신이 정말 네이티브 문에 DBMS에서 수행되고 있는지 확인하려면 당신이 persistence.xml에서 할 수있는 단지 기본 명령문의 출력을 활성화 또는 첫 번째 위치 : locks and oracle

+0

Preference 클래스에는 Entity (optimisticLock = OptimisticLockType.NONE)가 주석으로 달았습니다. 주어진 엔터티에 2PL 모델이 적용됩니다. 내가 잘못? – pbartosz

+0

예, Oracle 데이터베이스를 사용합니다. – pbartosz