zoukankan      html  css  js  c++  java
  • Hibernate锁

    悲观锁
    从加载对象就开始锁定。修改过程中一直是锁。直到commit()提交后再解锁。

    session.load(Info.class,"p003",LockOptions.UPGRADE);

    实例:

    public class TestPessimisticLock extends TestCase {
        @Test
        public void testLock1(){
            Session session = null;
            try {
                session = HibernateUtil.getSession();//开始锁定,下面的testLock2不能执行
                session.beginTransaction();
                
                Info data = session.load(Info.class, "p003", LockOptions.UPGRADE);
                data.setName("1111111");
                
                session.getTransaction().commit();//执行以后才解锁,这时testLock2才可以执行
            }  
            catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }
            finally{
                HibernateUtil.closeSession();
            }
        } 
        @Test
        public void testLock2(){
            Session session = null;
            try {
                session = HibernateUtil.getSession();
                session.beginTransaction();
                
                Info data = session.load(Info.class, "p003", LockOptions.UPGRADE);
                data.setName("2222222");
                
                session.getTransaction().commit();
            }  
            catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }
            finally{
                HibernateUtil.closeSession();
            }
        } 
    }

    乐观锁
    实际不算锁,只是多线程控制。在提交时间进行冲突检测。把里面的内容与刚开始读取的内容对照一下。有问题就抛异常。

    1.在数据库表中加一个字段version

    2.在实体类中加一个属性version

    public class Info implements java.io.Serializable {
    
        private String code;
        private Nation nation;
        private String name;
        private Boolean sex;
        private Date birthday;
        private Set families = new HashSet(0);
        private Set works = new HashSet(0);
        private int version;//添加一个属性version,并生成getter和setter
    
        public int getVersion() {
            return version;
        }
    
        public void setVersion(int version) {
            this.version = version;
        }

    3.在映谢文件中配置<version name="version"> 位置 放在<id></id>下面

    <hibernate-mapping>
        <class name="com.itnba.maya.model.Info" table="info" catalog="mydb" optimistic-lock="version">
            <cache usage="read-write"/>
            <id name="code" type="string">
                <column name="Code" length="50" />
                <generator class="assigned" />
            </id>
            
            <!-- 配置version,位置放在<id></id>下面 -->
            <version name="version"></version>
            
            <many-to-one name="nation" class="com.itnba.maya.model.Nation" fetch="select">
                <column name="Nation" length="50" />
            </many-to-one>
            <property name="name" type="string">
                <column name="Name" length="50" />
            </property>
            ....
     </class>
    </hibernate-mapping>

    其余代码不做改变。 

    实例:

    public class TestOptimisticLock extends TestCase{
        @Test
        public void testLock2(){
            Session session = null;
            try {
                session = HibernateUtil.getSession();
                session.beginTransaction();
                
                Info data = session.load(Info.class, "p002");
                data.setName("2222222");
                
                session.getTransaction().commit();//在此时进行冲突检测,version的值与刚开始读取的version值比较。值不同就就抛异常,意为无法操作。
            }  
            catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }
            finally{
                HibernateUtil.closeSession();
            }
        }
        @Test
        public void testLock1(){
            Session session = null;
            try {
                session = HibernateUtil.getSession();
                session.beginTransaction();
                
                Info data = session.load(Info.class, "p002");
                data.setName("1111111");
                
                session.getTransaction().commit();
            }  
            catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }
            finally{
                HibernateUtil.closeSession();
            }
        }
    }

     

    假如没有使用hibernate,那么这样来处理并发冲突 

    Info oldInfo = ...
    
    Info newInfo =...
    
    //where前面的内容用newInfo的属性,where后面的内容用oldInfo的属性
    update info set name=?,sex=?,nation=?,birthday=? where code=? and name=? and sex=? and nation=? and birthday=?
    
    
    executeUpdate(); //返回值为int,如果出现冲突,提示-更新的行数0----表示有并发冲突
  • 相关阅读:
    67. @Transactional的类注入失败【从零开始学Spring Boot】
    66. No EntityManager with actual transaction available for current thread【从零开始学】
    Android ShapeDrawable之OvalShape、RectShape、PaintDrawable、ArcShape
    Android渲染器Shader:环状放射渐变渲染器RadialGradient(三)
    Android渲染器Shader:梯度渐变扫描渲染器SweepGradient(二)
    Android弹幕编程设计实现的解决方案(一)
    65.什么是IOC?【从零开始学Spring Boot】
    64.JPA命名策略【从零开始学Spring Boot】
    事务、视图和索引
    存储过程
  • 原文地址:https://www.cnblogs.com/jonsnow/p/6534962.html
Copyright © 2011-2022 走看看