이 기사는 주로 아래에 자세히 설명 된 바와 같이 최대 절전 모드 비관적 자물쇠 및 낙관적 자물쇠의 모든 내용을 연구합니다.
비관적 잠금은 일반적으로 데이터베이스 메커니즘에 의해 구현됩니다. 전체 프로세스 중에 데이터가 잠겨 있습니다 (쿼리시). 물건이 출시되지 않는 한 (커밋/롤백), 어떤 사용자도이를보고 수정할 수 없습니다.
아래 사례를 통해 설명해 봅시다.
사례 : 상품의 인벤토리가 1000이고 회계사 1이 데이터를 꺼내 수정을 준비 할 때 일시적인 것이 있다면 그는 떠납니다. 이 기간 동안 회계 2는 데이터를 추출하고 수량을 200으로 빼고 회계 1이 다시 돌아와서 200 명까지 제거 된 수량을 빼 냈습니다. 이로 인해 문제가 발생했습니다. 회계 1은 800을 기준으로 수정하지 않았으며이를 업데이트 손실이라고하며 비관적 잠금을 사용하여 해결할 수 있습니다.
inventory.java :
공개 클래스 인벤토리 { /* 재고 번호* / 개인 문자열 itemNo; /* 재고 이름*/ 개인 문자열 itemName; /* 재고 수량*/ 개인 int 수량; // 세터 생략 및 getter 메서드}inventory.hbm.xml :
<? XML 버전 = "1.0"?> <! DocType Hibernate Mapping Public "-// Hibernate/Hibernate 매핑 DTD 3.0 // 테이블 = "t_inventory"> <!-기본 키의 수동 할당-> <id name = "itemno"> <generator // id> <!-매핑 속성-> <속성 이름 = "itemname"/> <속성 이름 = "수량"/> </class> </hibernate-mapping>
테스트 클래스 :
회계사 1은 비관적 잠금을 통해 데이터를로드하고 데이터를 수정합니다!
public void testload1 () {세션 세션 = 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 (예외 e) {e.printstacktrace (); session.getTransaction (). Rollback (); } 마침내 {hibernateutils.closesession (세션); }}회계사 2와 회계사 1은 동일한 작업을 가지고 있으며 둘 다 데이터베이스에서 데이터를 수정합니다!
public void testload2 () {세션 세션 = null; try {session = hibernateutils.getSession (); session.begintransaction (); /*데이터를로드 할 때 잠금 장치를 추가하여 다른 사람들이 데이터를 얻을 수 없도록하십시오*/ 인벤토리 invent = (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 (예외 e) {e.printstacktrace (); session.getTransaction (). Rollback (); } 마침내 {hibernateutils.closesession (세션); }}참고 : 두 회계사가 수행 한 운영은 동일합니다. 비관적 잠금 장치가 추가되면 회계사는 데이터를 꺼내 데이터를 수정합니다. 회계사 1이 물건을 제출하기 전에 회계사 2는 데이터에 액세스 할 수 없으며 대기 상태에만있을 수 있습니다. 회계사 1이 물건을 제출했다는 사실을 알게 된 후에 만 회계사 2는 데이터베이스의 데이터를 운영 할 기회가 있습니다.
위의 비관적 잠금 케이스를 통해 비관적 잠금의 가장 큰 장점은 업데이트 손실을 방지 할 수 있다는 것입니다. 계산기 1이 데이터를 처리하는 경우 계산기 2가 대기 상태 일 수 있습니다. 계산기 1을 제출 한 후에 만 계산기 2는 데이터를 수정할 기회가 있습니다. 그러나 큰 문제가 있습니다. 즉, 회계사 1이 데이터와 잎을 쿼리하는 경우 다른 사람들은 대부분의 하루를 기다려야합니다. 이 문제를 해결하기 위해 낙관적 잠금을 사용할 수 있습니다.
낙관적 자물쇠는 진정한 의미에서 잠금이 아닙니다. 대부분의 경우 데이터 버전 형식으로 구현됩니다. 일반적으로 버전 필드가 데이터베이스에 추가되며 데이터를 읽을 때 버전을 읽습니다. 데이터를 저장할 때 버전 값이 데이터베이스의 버전 값보다 작은 지 여부를 결정합니다. 적은 경우 업데이트되지 않으면 업데이트됩니다.
낙관적 잠금 장치에서 Javabean 설정, Inventory.java :
공개 클래스 인벤토리 { /*재고 번호* / 개인 문자열 itemNo; /*재고 이름*/ 개인 문자열 itemName; /*재고 수량*/ 개인 int 수량; /*데이터 버전*/ 개인 int 버전; // 세터 생략 및 getter 메서드}inventory.hbm.xml :
<? XML 버전 = "1.0"?> <! DocType Hibernate Mapping Public "-// hibernate/hibernate 매핑 dtd 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <! <! <! 신뢰-> <class name = "com.lixue.bean.inventory"table = "t_inventory"낙관적 lock = "버전"> <!-기본 키 매핑-> <id name = "itemno"> <generator/> </id> <!-데이터 버전은 기본 키 다음에 있어야합니다. 이름 = "수량"/> </class> </hibernate-mapping>
참고 : 낙관적 잠금을 사용한 매핑 파일은 기본 키 ID 이후에 버전 필드의 매핑이 먼저 매핑되어야한다고 규정합니다.
회계사 1 낙관적 잠금 상황에서 데이터를 처리합니다.
public void testload1 () {세션 세션 = null; try {session = hibernateutils.getSession (); session.begintransaction (); /*낙관적 잠금 하에서 데이터로드*/ 인벤토리 인벤토리 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 (예외 e) {e.printstacktrace (); session.getTransaction (). Rollback (); } 마침내 {hibernateutils.closesession (세션); }}회계사 2는 낙관적 잠금 하에서 데이터를 처리합니다 (회계사 2를 제출하지 않고 데이터를 처리 할 수 있습니다)
public void testload2 () {세션 세션 = null; try {session = hibernateutils.getSession (); session.begintransaction (); /*낙관적 잠금 하에서 데이터로드*/ 인벤토리 인벤토리 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 (예외 e) {e.printstacktrace (); session.getTransaction (). Rollback (); } 마침내 {hibernateutils.closesession (세션); }}참고 : 회계사가 데이터를 꺼내서 숫자를 200으로 빼고 제출하지 않는 전제로 회계사 2는 데이터를 운영 할 수도 있습니다. 이것은 비관적 잠금과 다릅니다. Accountant 2가 데이터를 작동하고 제출하면 데이터베이스의 데이터 버전 버전은 1로 추가됩니다. 그러면 회계사 1이 다시 제출되면 다시 데이터가 업데이트 된 것으로 나타납니다.이를 다시로드하십시오.
비관적 잠금 장치는 높은 동시성에 영향을 미치므로 낙관적 잠금을 사용하는 것이 좋습니다.
위의 내용은이 기사에서 최대 절전 모드 비관적 잠금 및 낙관적 잠금 예제에 대한 자세한 설명입니다. 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구는이 사이트의 다른 관련 주제를 계속 참조 할 수 있습니다. 단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!