zoukankan      html  css  js  c++  java
  • Hibernate的悲观锁和乐观锁

             前一篇博客我们从数据库角度分析,锁可以分为三种,分别为共享锁,独占锁和更新锁。我们从程序的角度来看锁可以分为两种类型,悲观锁和乐观锁,Hibernate提供对这两种锁 的支持,我们来了解一下Hibernate如何实现这两种锁。


    一、悲观锁 Pessimistic Locking

        

          通常由数据库机制实现,在查询的整个过程中把数据锁住,只要事务不释放(提交/回滚),那么其他任何用户都不能查看或修改数据,这种锁的方式是比较简单、直接。从开始就讲数据全部锁上,这种锁主要针对并发修改造成数据不一致的问题,但同时也会造成死锁的发生。

         适用场景:适合短事务

         示例:两个用户同时去到同一个数据100,用户1先将数据减20,这时数据库里的是80,用户2刚才读取到的是100,现在用户2,这样就会造成数据混乱。采用锁的方式解决这种问题。

     悲观锁:在用户1读取数据的时候,用锁将数据锁上,而用户2读取不到数据,只要用户1将数据修改后并提交,才释放锁,此时用户2才能读取到数据,而这时候读取到的是用户1修改后的数据,也就解决了数据混乱的问题了。

    实体类:

    public class Inventory {
    	private String itemNo;
    	private String itemName;
    	private int quantity;
    	
    	
    	public void setItemNo(String itemNo) {
    		this.itemNo = itemNo;
    	}
    	public String getItemName() {
    		return itemName;
    	}
    	public void setItemName(String itemName) {
    		this.itemName = itemName;
    	}
    	public int getQuantity() {
    		return quantity;
    	}
    	public void setQuantity(int quantity) {
    		this.quantity = quantity;
    	}
    	
    	
    	
    }


    配置文件:

    <hibernate-mapping>
    	<class name="com.bjpowernode.hibernate.Inventory" table="t_inventory">
    		<id name="itemNo">
    			<generator class="assigned"/>
    		</id>
    		<property name="itemName"/>
    		<property name="quantity"/>
    		
    	</class>
    	
    </hibernate-mapping>


    LockModel(使用UPGRADE)

    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----ItemNname ="+inv.getItemName());
    			System.out.println("opt1----Quantity ="+inv.getQuantity());
    			
    			session.beginTransaction().commit();
    		}catch(Exception e){
    			e.printStackTrace();
    			session.getTransaction().rollback();
    		}finally{
    			HibernateUtils.closeSession(session);
    		}
    	}


    二、乐观锁OptimisticLocking

         

            不是锁,是一种冲突检测机制,乐观锁的并发性要好于悲观锁。常用的方式可以使用数据版本的方式(version)实现,一般是在数据库中加入一个version字段,在读取数据的时候将version字段读取出来,在保存数据的时候判断version的值是否小于数据库中version的版本,如果小于不予更新,否则更新数据。

    实体类:

         在实体类配置中添加上版本的映射

    public class Inventory {
    	private String itemNo;
    	private String itemName;
    	private int quantity;
    	private int version;
    	
    	public int getVersion() {
    		return version;
    	}
    	public void setVersion(int version) {
    		this.version = version;
    	}
    	public String getItemNo() {
    		return itemNo;
    	}
    	public void setItemNo(String itemNo) {
    		this.itemNo = itemNo;
    	}
    	public String getItemName() {
    		return itemName;
    	}
    	public void setItemName(String itemName) {
    		this.itemName = itemName;
    	}
    	public int getQuantity() {
    		return quantity;
    	}
    	public void setQuantity(int quantity) {
    		this.quantity = quantity;
    	}	
    	
    }


    配置文件:

    <hibernate-mapping>
        <class name="com.bjpowernode.hibernate.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>


      使用方式还是和之前的一样,这样在更新之前就会跟数据库中版本对比,能够更好的解决数据混乱的问题。


    总结:

          数据库添加锁的两种方式,悲观锁简单明了,它将一切都以悲观的眼光来看待,认为一切都是并发的,而且当数据库很大或者遇到问题就很容易造成死锁。乐观锁的方式更加和谐,能够更好的处理并发问题。



  • 相关阅读:
    做一个项目,平时都用到哪些工具提高效率(上)
    做项目时,如何做比较美观大方的数据输入窗体
    做一个项目,平时都用到哪些工具提高效率(中)
    类型的初试化器的调用时机
    数据加密小工具
    ASP.NET 开发知识小结
    做一个项目,平时都用到哪些工具提高效率(下)
    两道面试题目 关于new和override的
    js技巧,js找到html中的注释,js让客户端另存一段文本
    在适当的场合使用FlagsAttribute修饰枚举
  • 原文地址:https://www.cnblogs.com/zsswpb/p/6329432.html
Copyright © 2011-2022 走看看