欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Hibernate悲觀鎖和樂觀鎖實(shí)例詳解

 更新時(shí)間:2018年02月07日 16:19:07   作者:lavimer  
這篇文章主要介紹了Hibernate悲觀鎖和樂觀鎖實(shí)例詳解,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下

本文研究的主要是Hibernate悲觀鎖和樂觀鎖的全部內(nèi)容,具體介紹如下。

悲觀鎖

悲觀鎖通常是由數(shù)據(jù)庫機(jī)制實(shí)現(xiàn)的,在整個(gè)過程中把數(shù)據(jù)鎖住(查詢時(shí)),只要事物不釋放(提交/回滾),那么任何用戶都不能查看或修改。

下面我們通過一個(gè)案例來說明。

案例:假設(shè)貨物庫存為1000,當(dāng)核算員1取出了數(shù)據(jù)準(zhǔn)備修改,但臨時(shí)有事,就走了。期間核算員2取出了數(shù)據(jù)把數(shù)量減去200,然后核算員1回來了把剛才取出的數(shù)量減去200,這就出現(xiàn)了一個(gè)問題,核算員1并沒有在800的基礎(chǔ)上做修改。這就是所謂的更新丟失,采用悲觀鎖可以解決。

Inventory.java:

public class Inventory { 
 
  /* 存貨編號(hào) */ 
  private String itemNo; 
  /* 存貨名稱 */ 
  private String itemName; 
  /* 存貨數(shù)量 */ 
  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"> 
    <!-- 主鍵手動(dòng)分配 --> 
    <id name="itemNo"> 
      <generator class="assigned"/> 
    </id> 
    <!-- 映射屬性 --> 
    <property name="itemName"/> 
    <property name="quantity"/> 
  </class> 
</hibernate-mapping> 

測試類:

核算員1通過悲觀鎖的方式加載數(shù)據(jù),并對數(shù)據(jù)進(jìn)行修改!

public void testLoad1() { 
    Session session = null; 
    try { 
      session = HibernateUtils.getSession(); 
      session.beginTransaction(); 
      /*在加載的時(shí)候就加上一把悲觀鎖,讓其他用戶都無法訪問*/ 
      Inventory inv = (Inventory) session.load(Inventory.class, "1001", LockMode.UPGRADE); 
      /*獲取數(shù)據(jù)*/ 
      System.out.println("opt1-->itemNo=" + inv.getItemNo()); 
      System.out.println("opt1-->itemName=" + inv.getItemName()); 
      System.out.println("opt1-->quantity=" + inv.getQuantity()); 
      /*數(shù)量減去200*/ 
      inv.setQuantity(inv.getQuantity() - 200); 
 
      session.getTransaction().commit(); 
    } catch (Exception e) { 
      e.printStackTrace(); 
      session.getTransaction().rollback(); 
    } finally { 
      HibernateUtils.closeSession(session); 
    } 
  } 

核算員2和核算員1的操作相同,都是對數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行修改!

public void testLoad2() { 
    Session session = null; 
    try { 
      session = HibernateUtils.getSession(); 
      session.beginTransaction(); 
      /*在加載數(shù)據(jù)的時(shí)候就加上一把鎖,讓其他人無法獲取數(shù)據(jù)*/ 
      Inventory inv = (Inventory) session.load(Inventory.class, "1001", LockMode.UPGRADE); 
      /*獲取真實(shí)數(shù)據(jù)*/ 
      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); 
    } 
  } 

注:兩個(gè)核算員做的操作相同,如果加了悲觀鎖之后,核算員取出了數(shù)據(jù)并對數(shù)據(jù)進(jìn)行修改,在核算員1沒有提交事物之前,核算員2是不能對數(shù)據(jù)進(jìn)行訪問的,只能處于等待狀態(tài)。知道核算員1把事物提交了之后,核算員2才有機(jī)會(huì)對數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行操作。

通過上面悲觀鎖的案例我們可以發(fā)現(xiàn),悲觀鎖最大的好處就是可以防止更新丟失,當(dāng)核算員1在處理數(shù)據(jù)的時(shí)候,核算員2只能處于等待狀態(tài),只有核算員1提交了事物之后,核算員2才有機(jī)會(huì)修改數(shù)據(jù)。但是也存在一個(gè)很大的問題,那就是,如果核算員1將數(shù)據(jù)查詢出來后人就走掉了,那么其他人就得等上大半天,非常浪費(fèi)時(shí)間,為了解決這個(gè)問題,我們可以使用樂觀鎖。

樂觀鎖

樂觀鎖并不是真正意義上的鎖,大多數(shù)情況下是采用數(shù)據(jù)版本(version)的方式實(shí)現(xiàn),一般在數(shù)據(jù)庫中加入一個(gè)version字段,在讀取數(shù)據(jù)的時(shí)候就將version讀取出來,在保存數(shù)據(jù)的時(shí)候判斷version的值是否小于數(shù)據(jù)庫的version值,如果小于則不予更新,否則給予更新。

樂觀鎖下的javaBean設(shè)置,Inventory.java:

public class Inventory { 
   
  /*存貨編號(hào)*/ 
  private String itemNo; 
  /*存貨名稱*/ 
  private String itemName; 
  /*存貨數(shù)量*/ 
  private int quantity; 
  /*數(shù)據(jù)版本*/ 
  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標(biāo)簽中加上optimistc-lock屬性,其值為版本信心 --> 
  <class name="com.lixue.bean.Inventory" table="t_inventory" optimistic-lock="version"> 
    <!-- 主鍵映射 --> 
    <id name="itemNo"> 
      <generator class="assigned"/> 
    </id> 
    <!-- 數(shù)據(jù)版本,必須在主鍵后面的位置 --> 
    <version name="version"/> 
    <!-- 基本屬性映射 --> 
    <property name="itemName"/> 
    <property name="quantity"/> 
  </class> 
</hibernate-mapping> 

注:使用樂觀鎖的映射文件有規(guī)定即version字段的映射必須在主鍵ID之后第一個(gè)被映射。

測試:

核算員1在樂觀鎖的情況下處理數(shù)據(jù):

public void testLoad1() { 
    Session session = null; 
    try { 
      session = HibernateUtils.getSession(); 
      session.beginTransaction(); 
      /*樂觀鎖下加載數(shù)據(jù)*/ 
      Inventory inv = (Inventory)session.load(Inventory.class, "1001"); 
      /*實(shí)際獲取數(shù)據(jù)*/ 
      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()); 
      /*數(shù)量減去200*/ 
      inv.setQuantity(inv.getQuantity() - 200); 
       
      session.getTransaction().commit(); 
    }catch(Exception e) { 
      e.printStackTrace(); 
      session.getTransaction().rollback(); 
    }finally { 
      HibernateUtils.closeSession(session); 
    } 
  } 

核算員2在樂觀鎖的情況下處理數(shù)據(jù)(核算員2可以在核算員1未提交數(shù)據(jù)的前提下處理數(shù)據(jù))

public void testLoad2() { 
    Session session = null; 
    try { 
      session = HibernateUtils.getSession(); 
      session.beginTransaction(); 
      /*樂觀鎖下加載數(shù)據(jù)*/ 
      Inventory inv = (Inventory)session.load(Inventory.class, "1001"); 
      /*實(shí)際獲取數(shù)據(jù)*/ 
      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()); 
      /*數(shù)量減去200*/ 
      inv.setQuantity(inv.getQuantity() - 200); 
       
      session.getTransaction().commit(); 
    }catch(Exception e) { 
      e.printStackTrace(); 
      session.getTransaction().rollback(); 
    }finally { 
      HibernateUtils.closeSession(session); 
    } 
  }  

注:在核算員取出數(shù)據(jù)將數(shù)量減去200之后并未提交的前提下,核算員2也可以操作數(shù)據(jù),這就有別于悲觀鎖,當(dāng)核算員2操作了數(shù)據(jù)并且提交之后,數(shù)據(jù)庫中數(shù)據(jù)版本version就會(huì)加1,那么當(dāng)核算員1在回來進(jìn)行事物提交時(shí)就會(huì)出現(xiàn)錯(cuò)誤提示即數(shù)據(jù)已更新,請重新加載。

總結(jié)

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

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

相關(guān)文章

  • rocketmq client 日志的問題處理方式

    rocketmq client 日志的問題處理方式

    這篇文章主要介紹了rocketmq client 日志的問題處理方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java生成word文檔的示例詳解

    Java生成word文檔的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用Java語言生成word文檔,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以參考一下
    2022-12-12
  • 實(shí)例講解Java中random.nextInt()與Math.random()的基礎(chǔ)用法

    實(shí)例講解Java中random.nextInt()與Math.random()的基礎(chǔ)用法

    今天小編就為大家分享一篇關(guān)于實(shí)例講解Java中random.nextInt()與Math.random()的基礎(chǔ)用法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • java 中函數(shù)的參數(shù)傳遞詳細(xì)介紹

    java 中函數(shù)的參數(shù)傳遞詳細(xì)介紹

    這篇文章主要介紹了 java 中函數(shù)的參數(shù)傳遞詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • springboot+vue實(shí)現(xiàn)阿里云oss大文件分片上傳的示例代碼

    springboot+vue實(shí)現(xiàn)阿里云oss大文件分片上傳的示例代碼

    阿里云推出了直傳,本文主要介紹了springboot+vue實(shí)現(xiàn)阿里云oss大文件分片上傳的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • 詳解spring boot引入外部jar包的坑

    詳解spring boot引入外部jar包的坑

    本篇文章主要介紹了spring boot引入外部jar的坑,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • java高并發(fā)的ReentrantLock重入鎖

    java高并發(fā)的ReentrantLock重入鎖

    這篇文章主要介紹了如何教你完全理解ReentrantLock重入鎖,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,下面我們來一起學(xué)習(xí)一下吧
    2021-10-10
  • mybatis where 標(biāo)簽使用

    mybatis where 標(biāo)簽使用

    where標(biāo)記的作用類似于動(dòng)態(tài)sql中的set標(biāo)記,本文主要介紹了mybatis where 標(biāo)簽使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • SpringMVC中的@RequestMapping注解的使用詳細(xì)教程

    SpringMVC中的@RequestMapping注解的使用詳細(xì)教程

    @RequestMapping注解的作用就是將請求和處理請求的控制器方法關(guān)聯(lián)起來,建立映射關(guān)系,本文主要來和大家詳細(xì)講講它的具體使用,感興趣的可以了解一下
    2023-07-07
  • 詳解Windows?配置Java環(huán)境變量的方法

    詳解Windows?配置Java環(huán)境變量的方法

    這篇文章主要介紹了Windows?配置Java環(huán)境變量,通過配置JAVA_HOME環(huán)境變量,配置Path環(huán)境變量的過程解析,給大家詳細(xì)介紹了java環(huán)境變量的配置過程,需要的朋友可以參考下
    2022-04-04

最新評論