• hibernate>悲观锁和乐观锁 小强斋


    一、悲观锁

    悲观锁的实现,通常依赖于数据库机制,在整个过程中将数据锁定,其它任何用户都不能读取或修改

    悲观锁的实现:

    显式的用户指定"可以通过以下几种方式之一来表示:

    • 调用 Session.load()的时候指定锁定模式(LockMode)

    • 调用Session.lock()

    • 调用Query.setLockMode()

    package com.wsz.test;
    
    import junit.framework.TestCase;
    
    import org.hibernate.LockMode;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    
    import com.wsz.entity.HibernateUtils;
    import com.wsz.entity.Products;
    
    public class Test extends TestCase {
    
    	public void testSave() {
    		Session session = null;
    		Transaction tx = null;
    		Products products = null;
    		try {
    			session = HibernateUtils.getSession();
    			tx = session.beginTransaction();
                products=new Products();
                products.setName("脑白金");
                products.setTotalnumber(1000);
                session.save(products);
    			tx.commit();
    		} catch (Exception e) {
    			e.printStackTrace();
    			tx.rollback();
    		} finally {
    			HibernateUtils.closeSession(session);
    		}
    
    	}
    
    	public void test1() {
    
    		Products products = new Products();
    		Session session = HibernateUtils.getSession();
    		session.beginTransaction();
    		//悲观锁的实现
    		products = (Products) session.load(products.getClass(), 1,LockMode.UPGRADE);
    		System.out.print(products.getName());
    		System.out.println(products.getTotalnumber());
    		products.setTotalnumber(products.getTotalnumber()-200);
    		session.getTransaction().commit();
    
    	}
    	
    	
    	public void test2() {
    
    		Products products = new Products();
    		Session session = HibernateUtils.getSession();
    		session.beginTransaction();
    		products = (Products) session.load(products.getClass(), 1,LockMode.UPGRADE);
    		System.out.print(products.getName());
    		System.out.println(products.getTotalnumber());
    		products.setTotalnumber(products.getTotalnumber()-200);
    		session.getTransaction().commit();
    
    	}
    
    }
    

    使用悲观锁,lazy属性失效,立即发出sql。

    二、乐观锁

    大多数基于数据版本记录机制(version)实现,一般是在数据库表中加入一个version字段,读取数据时将版本号一同读出,之后更新数据时版本号加一,如果提交数据时版本号小于或等于数据表中的版本号,则认为数据是过期的,否则给予更新。

    Products.hbm.xml

    <hibernate-mapping>
    	<class name="com.wsz.entity.Products" table="t_products" optimistic-lock="version">
    		<id name="id">
    			<generator class="native" />
    		</id>
    		<version name="version"/>
    		<property name="name" />
    		<property name="totalnumber" />
    	</class>
    </hibernate-mapping>

    数据库表多了一个version字段

    开始version=0

    如果更新后 version=1,由数据库自动更新。

    Products.java

    package com.wsz.entity;
    
    
    public class Products {
    	private int id;
    	private String name;
    	private int  totalnumber;
    	private int version;
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getTotalnumber() {
    		return totalnumber;
    	}
    	public void setTotalnumber(int totalnumber) {
    		this.totalnumber = totalnumber;
    	}
    	public int getVersion() {
    		return version;
    	}
    	public void setVersion(int version) {
    		this.version = version;
    	}
    	
    
    
    
    }
    

    Test.java

    package com.wsz.test;
    
    import junit.framework.TestCase;
    
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    
    import com.wsz.entity.HibernateUtils;
    import com.wsz.entity.Products;
    
    public class Test extends TestCase {
    
    	public void testSave() {
    		Session session = null;
    		Transaction tx = null;
    		Products products = null;
    		try {
    			session = HibernateUtils.getSession();
    			tx = session.beginTransaction();
                products=new Products();
                products.setName("naobaijin");
                products.setTotalnumber(1000);
                session.save(products);
    			tx.commit();
    		} catch (Exception e) {
    			e.printStackTrace();
    			tx.rollback();
    		} finally {
    			HibernateUtils.closeSession(session);
    		}
    
    	}
    
    	public void test1() {
    
    		Products products = new Products();
    		Session session = HibernateUtils.getSession();
    		session.beginTransaction();
    		//悲观锁的实现
    		products = (Products) session.load(products.getClass(), 1);
    		System.out.print(products.getName());
    		System.out.println(products.getTotalnumber());
    		products.setTotalnumber(products.getTotalnumber()-200);
    		session.getTransaction().commit();
    
    	}
    	
    	
    	public void test2() {
    
    		Products products = new Products();
    		Session session = HibernateUtils.getSession();
    		session.beginTransaction();
    		products = (Products) session.load(products.getClass(), 1);
    		System.out.print(products.getName());
    		System.out.println(products.getTotalnumber());
    		products.setTotalnumber(products.getTotalnumber()-200);
    		session.getTransaction().commit();
    
    	}
    
    }
    

    使用悲观锁,lazy不会失效,不会立即发出sql

    更新时发出的sql语句Hibernate: update t_products set version=?, name=?, totalnumber=? where id=? and version=?,

    如果test1更新了,在commit设置断点,没有提交,test2更新了。此时test1往下运行,当前的version 小于数据库的version ,会生成如下的异常。

    10:48:59,260 ERROR AbstractFlushingEventListener:301 - Could not synchronize database state with session
    org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.wsz.entity.Products#1]
     at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1699) 


     

  • 相关阅读:
    TensorFlow笔记-初识
    SMP、NUMA、MPP体系结构介绍
    Page Cache, the Affair Between Memory and Files.页面缓存-内存与文件的那些事
    How The Kernel Manages Your Memory.内核是如何管理内存的
    Anatomy of a Program in Memory.剖析程序的内存布局
    Cache: a place for concealment and safekeeping.Cache: 一个隐藏并保存数据的场所
    Memory Translation and Segmentation.内存地址转换与分段
    CPU Rings, Privilege, and Protection.CPU的运行环, 特权级与保护
    The Kernel Boot Process.内核引导过程
    How Computers Boot Up.计算机的引导过程
  • 原文地址:https://www.cnblogs.com/xiaoqiangzhaitai/p/5637504.html
Copyright © 2020-2023  润新知