Hibernate 비관 자물쇠 와 낙관 자물쇠 실례 상세 설명

본 고 는 주로 Hibernate 비관 자물쇠 와 낙관 자물쇠 의 모든 내용 을 연구 하 는데 구체 적 으로 다음 과 같이 소개 한다.
비관 적 자물쇠
비관 적 인 자 물 쇠 는 보통 데이터 베이스 체제 에 의 해 이 루어 집 니 다.전체 과정 에서 데 이 터 를 잠 그 고(조회 할 때)사물 이 풀 리 지 않 으 면 그 어떠한 사용자 도 보 거나 수정 할 수 없습니다.
다음은 하나의 사례 를 통 해 설명 하 겠 습 니 다.

사례:화물 재고 가 1000 이 라 고 가정 하고 계산 원 1 이 데 이 터 를 꺼 내 수정 을 준 비 했 으 나 잠시 일이 있어 가 버 렸 다.그 동안 채산 원 2 는 데 이 터 를 꺼 내 200 을 빼 고 채산 원 1 이 돌 아 왔 다.방금 꺼 낸 수량 을 200 을 빼 면 문제 가 생 겼 다.채산 원 1 은 800 을 바탕 으로 수정 하지 않 았 다.이른바 업데이트 분실 이라는 비관 적 인 자물쇠 로 해결 할 수 있다.
Inventory.java:

public class Inventory { 
 
  /*      */ 
  private String itemNo; 
  /*      */ 
  private String itemName; 
  /*      */ 
  private int quantity; 
 
  //  setter getter   
} 
Inventory.hbm.xml:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC  
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping> 
  <class name="com.lixue.bean.Inventory" table="t_inventory"> 
    <!--        --> 
    <id name="itemNo"> 
      <generator class="assigned"/> 
    </id> 
    <!--      --> 
    <property name="itemName"/> 
    <property name="quantity"/> 
  </class> 
</hibernate-mapping> 
테스트 클래스:
채산 원 1 비관 적 잠 금 방식 으로 데 이 터 를 불 러 오고 데 이 터 를 수정 합 니 다!

public void testLoad1() { 
    Session session = null; 
    try { 
      session = HibernateUtils.getSession(); 
      session.beginTransaction(); 
      /*              ,          */ 
      Inventory inv = (Inventory) session.load(Inventory.class, "1001", LockMode.UPGRADE); 
      /*    */ 
      System.out.println("opt1-->itemNo=" + inv.getItemNo()); 
      System.out.println("opt1-->itemName=" + inv.getItemName()); 
      System.out.println("opt1-->quantity=" + inv.getQuantity()); 
      /*    200*/ 
      inv.setQuantity(inv.getQuantity() - 200); 
 
      session.getTransaction().commit(); 
    } catch (Exception e) { 
      e.printStackTrace(); 
      session.getTransaction().rollback(); 
    } finally { 
      HibernateUtils.closeSession(session); 
    } 
  } 
계산 원 2 와 계산 원 1 의 조작 이 같 고 모두 데이터 베 이 스 를 수정 합 니 다!

public void testLoad2() { 
    Session session = null; 
    try { 
      session = HibernateUtils.getSession(); 
      session.beginTransaction(); 
      /*              ,          */ 
      Inventory inv = (Inventory) session.load(Inventory.class, "1001", LockMode.UPGRADE); 
      /*      */ 
      System.out.println("opt2-->itemNo=" + inv.getItemNo()); 
      System.out.println("opt2-->itemName=" + inv.getItemName()); 
      System.out.println("opt2-->quantity=" + inv.getQuantity()); 
      /*    200*/ 
      inv.setQuantity(inv.getQuantity() - 200); 
 
      session.getTransaction().commit(); 
    } catch (Exception e) { 
      e.printStackTrace(); 
      session.getTransaction().rollback(); 
    } finally { 
      HibernateUtils.closeSession(session); 
    } 
  } 
주:두 계산 원 이 하 는 조작 이 같 습 니 다.비관 적 인 자 물 쇠 를 추가 한 후에 계산 원 이 데 이 터 를 꺼 내 데 이 터 를 수정 하면 계산 원 1 이 사물 을 제출 하지 않 기 전에 계산 원 2 는 데 이 터 를 방문 할 수 없고 대기 상태 에 있 을 수 밖 에 없습니다.채산 원 1 이 사물 을 제출 한 것 을 알 고 채산 원 2 는 데이터베이스 에 있 는 데 이 터 를 조작 할 기회 가 있 었 다.
위의 비관 적 인 잠 금 사례 를 통 해 알 수 있 듯 이 비관 적 인 잠 금 의 가장 큰 장점 은 업데이트 손실 을 방지 하 는 것 이다.계산 원 1 이 데 이 터 를 처리 할 때 계산 원 2 는 대기 상태 에 있 을 수 밖 에 없고 계산 원 1 이 사물 을 제출 한 후에 야 계산 원 2 가 데 이 터 를 수정 할 수 있다.그러나 큰 문제 도 존재 한다.즉,채산 원 1 이 데 이 터 를 조회 한 후에 가 버 리 면 다른 사람들 은 반나절 을 기 다 려 야 하고 시간 을 낭비 하 는 것 이다.이 문 제 를 해결 하기 위해 우 리 는 낙관적 인 자 물 쇠 를 사용 할 수 있다.
낙관적 자물쇠
낙관적 인 잠 금 은 진정한 의미 의 잠 금 이 아 닙 니 다.대부분의 경우 데이터 버 전(version)방식 으로 이 루어 집 니 다.일반적으로 데이터베이스 에 version 필드 를 추가 하고 데 이 터 를 읽 을 때 version 을 읽 습 니 다.데 이 터 를 저장 할 때 version 의 값 이 데이터베이스 의 version 값 보다 작은 지 판단 합 니 다.작 으 면 업데이트 하지 않 습 니 다.그렇지 않 으 면 업 데 이 트 를 합 니 다.
낙관적 으로 잠 긴 javaBean 설정,Inventory.java:

public class Inventory { 
   
  /*    */ 
  private String itemNo; 
  /*    */ 
  private String itemName; 
  /*    */ 
  private int quantity; 
  /*    */ 
  private int version; 
 
  //  setter getter   
} 
Inventory.hbm.xml:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC  
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping> 
  <!--  class     optimistc-lock  ,        --> 
  <class name="com.lixue.bean.Inventory" table="t_inventory" optimistic-lock="version"> 
    <!--      --> 
    <id name="itemNo"> 
      <generator class="assigned"/> 
    </id> 
    <!--     ,           --> 
    <version name="version"/> 
    <!--        --> 
    <property name="itemName"/> 
    <property name="quantity"/> 
  </class> 
</hibernate-mapping> 
주:낙관적 인 잠 금 을 사용 하 는 맵 파일 은 version 필드 의 맵 이 홈 키 ID 이후 에 첫 번 째 로 매 핑 되 어야 한 다 는 규정 이 있 습 니 다.
테스트:
채산 원 1 낙관적 인 잠 금 상태 에서 데 이 터 를 처리 합 니 다.

public void testLoad1() { 
    Session session = null; 
    try { 
      session = HibernateUtils.getSession(); 
      session.beginTransaction(); 
      /*        */ 
      Inventory inv = (Inventory)session.load(Inventory.class, "1001"); 
      /*      */ 
      System.out.println("opt1-->itemNo=" + inv.getItemNo()); 
      System.out.println("opt1-->itemName=" + inv.getItemName()); 
      System.out.println("opt1-->version=" + inv.getVersion()); 
      System.out.println("opt1-->quantity=" + inv.getQuantity()); 
      /*    200*/ 
      inv.setQuantity(inv.getQuantity() - 200); 
       
      session.getTransaction().commit(); 
    }catch(Exception e) { 
      e.printStackTrace(); 
      session.getTransaction().rollback(); 
    }finally { 
      HibernateUtils.closeSession(session); 
    } 
  } 
채산 원 2 낙관적 인 잠 금 상태 에서 데 이 터 를 처리 합 니 다(채산 원 2 는 채산 원 1 이 데 이 터 를 제출 하지 않 은 전제 에서 데 이 터 를 처리 할 수 있 습 니 다)

public void testLoad2() { 
    Session session = null; 
    try { 
      session = HibernateUtils.getSession(); 
      session.beginTransaction(); 
      /*        */ 
      Inventory inv = (Inventory)session.load(Inventory.class, "1001"); 
      /*      */ 
      System.out.println("opt2-->itemNo=" + inv.getItemNo()); 
      System.out.println("opt2-->itemName=" + inv.getItemName()); 
      System.out.println("opt2-->version=" + inv.getVersion()); 
      System.out.println("opt2-->quantity=" + inv.getQuantity()); 
      /*    200*/ 
      inv.setQuantity(inv.getQuantity() - 200); 
       
      session.getTransaction().commit(); 
    }catch(Exception e) { 
      e.printStackTrace(); 
      session.getTransaction().rollback(); 
    }finally { 
      HibernateUtils.closeSession(session); 
    } 
  }  
주:채산 원 이 데 이 터 를 꺼 내 200 을 뺀 후에 제출 하지 않 은 전제 에서 채산 원 2 도 데 이 터 를 조작 할 수 있 습 니 다.이것 은 비관 적 인 자물쇠 와 달리 채산 원 2 가 데 이 터 를 조작 하고 제출 한 후에 데이터 베이스 에 데이터 버 전 version 이 1 을 추가 합 니 다.그러면 채산 원 1 이 돌아 와 서 사물 을 제출 할 때 오류 알림 이 발생 합 니 다.즉,데이터 가 업데이트 되 었 으 니 다시 불 러 오 십시오.
총결산
비관 적 인 자 물 쇠 는 높 은 병발 에 영향 을 미 치기 때문에 낙관적 인 자 물 쇠 를 사용 하 는 것 이 좋다.
이상 은 바로 본 고 에서 Hibernate 비관 적 인 자물쇠 와 낙관적 인 자물쇠 사례 에 대한 상세 한 설명 의 모든 내용 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.관심 이 있 는 친 구 는 본 사이트 의 다른 관련 주 제 를 계속 참고 할 수 있 습 니 다.부족 한 점 이 있 으 면 댓 글로 지적 해 주 십시오.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기