最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Hibernate悲觀鎖和樂觀鎖實例詳解

 更新時間:2018年02月07日 16:19:07   作者:lavimer  
這篇文章主要介紹了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是不能對數據進行訪問的,只能處于等待狀態(tài)。知道核算員1把事物提交了之后,核算員2才有機會對數據庫中的數據進行操作。

通過上面悲觀鎖的案例我們可以發(fā)現,悲觀鎖最大的好處就是可以防止更新丟失,當核算員1在處理數據的時候,核算員2只能處于等待狀態(tài),只有核算員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> 

注:使用樂觀鎖的映射文件有規(guī)定即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在回來進行事物提交時就會出現錯誤提示即數據已更新,請重新加載。

總結

悲觀鎖會影響高并發(fā),所以用樂觀鎖比較好。

以上就是本文關于Hibernate悲觀鎖和樂觀鎖實例詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

相關文章

  • java線程池的四種創(chuàng)建方式詳細分析

    java線程池的四種創(chuàng)建方式詳細分析

    這篇文章主要介紹了java線程池的四種創(chuàng)建方式詳細分析,連接池是創(chuàng)建和管理一個連接的緩沖池的技術,這些連接準備好被任何需要它們的線程使用
    2022-07-07
  • Java編程細節(jié)重構之為什么if-else不是好代碼詳析

    Java編程細節(jié)重構之為什么if-else不是好代碼詳析

    這篇文章主要給大家介紹了關于Java編程細節(jié)重構之為什么if-else不是好代碼的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學些學習吧
    2018-09-09
  • Java實體類中Set按照對象的某個字段對set排序

    Java實體類中Set按照對象的某個字段對set排序

    這篇文章主要介紹了Java實體類中Set按照對象的某個字段對set排序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-06-06
  • Java多線程的用法詳解

    Java多線程的用法詳解

    本篇文章介紹了,在Java中多線程的用法詳解。需要的朋友參考下
    2013-04-04
  • 如何使用Playwright對Java API實現自動視覺測試

    如何使用Playwright對Java API實現自動視覺測試

    這篇文章主要介紹了如何使用Playwright對Java API實現自動視覺測試,幫助大家更好的理解和使用Playwright,感興趣的朋友可以了解下
    2021-01-01
  • 如何實現自定義SpringBoot的Starter組件

    如何實現自定義SpringBoot的Starter組件

    這篇文章主要介紹了實現自定義SpringBoot的Starter組件的示例代碼,想要自定義starter組件,首先要了解springboot是如何加載starter的,也就是springboot的自動裝配機制原理,本文結合示例代碼詳細講解,需要的朋友可以參考下
    2023-02-02
  • 詳解Java數組的排序算法與二分查找法

    詳解Java數組的排序算法與二分查找法

    這篇文章詳細給大家介紹了Java數組的排序算法與二分查找法,文中有詳細的代碼示例,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2023-05-05
  • Spring Boot集成Druid數據庫連接池

    Spring Boot集成Druid數據庫連接池

    這篇文章主要介紹了Spring Boot集成Druid數據庫連接池,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • java接口私有方法實現過程解析

    java接口私有方法實現過程解析

    這篇文章主要介紹了java接口私有方法實現過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • 深入探討Java應用性能監(jiān)控與調優(yōu)的工具鏈構建

    深入探討Java應用性能監(jiān)控與調優(yōu)的工具鏈構建

    這篇文章主要來和大家將深入探討Java應用性能監(jiān)控與調優(yōu)的完整工具鏈,從傳統(tǒng)的單機分析工具JProfiler到現代化的分布式監(jiān)控系統(tǒng)Prometheus,希望能幫助開發(fā)者和運維人員構建全方位的性能監(jiān)控體系
    2025-06-06

最新評論

榆树市| 芜湖市| 西充县| 丰台区| 黎平县| 大化| 建平县| 耒阳市| 西青区| 绥中县| 文安县| 营口市| 朝阳区| 六枝特区| 灌云县| 湘阴县| 阳东县| 舞钢市| 浦江县| 嘉荫县| 额济纳旗| 科技| 子洲县| 都匀市| 湖口县| 巴里| 青冈县| 张北县| 营山县| 吕梁市| 封丘县| 乌兰县| 那坡县| 甘孜| 青州市| 鄯善县| 敦化市| 浪卡子县| 陈巴尔虎旗| 习水县| 福鼎市|