• day36 10-Hibernate中的事务:解决丢失更新


    演示hibernate如何产生丢失更新的


     丢失更新是怎么玩的?首先两个事务先都把它查出来。

    A事务里面去修改的数据没了,被B事务覆盖掉了。这是被B事务提交覆盖,B事务回滚也能覆盖。这就是丢失更新的效果。


    悲观锁使用了数据库的锁机制,

    这就是悲观锁的解决方案,但是这种方式并不是特别的好。因为这条记录被锁定了,其他人都不能操作这条记录了。必须等排它锁被释放完其他人才能操作,这是悲观锁来解决。


     乐观锁来解决。

    这是关于session的一些本地操作,一会我们来说它。

     


    乐观锁是怎么做的?相当于在我们这里加了一个版本号。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
     
    <hibernate-mapping package="cn.itcast.vo"><!-- 如果这里配置了包名下面可以不用写 -->
    <!--
    <hibernate-mapping>
    -->
    <!--  
        <class name="cn.itcast.hibernate3.demo2.Customer" table="customer">
        -->
        <!-- 
        <class name="cn.itcast.vo.Customer" table="customer">
            -->
                <class name="Customer" batch-size="2" table="customer">
            <!-- 配置唯一标识 -->
            <id name="cid" column="cid">
                <generator class="native"/>
            </id>
            <!-- version标签是版本号 -->
            <version name="version"></version>
            <!-- 配置普通属性 -->
            <property name="cname" column="cname" length="30"/>
            <property name="age" column="age" length="30"/>
            
            <!-- 建立映射 -->
            <!-- 配置一个集合 <set>的name Customer对象中的关联对象的属性名称. -->
            <!-- 这里把级联去掉  要最简短的配置 
            <set name="orders" cascade="save-update" inverse="true">
    -->
    <set name="orders" cascade="save-update" batch-size="2">
                <!-- <key>标签中column:用来描述一对多多的一方的外键的名称. -->
                <key column="cno"></key>
                <!-- 配置一个<one-to-many>标签中class属性:订单的类的全路径 -->
                <!--  
                <one-to-many class="cn.itcast.hibernate3.demo2.Order"/>
                -->
                <one-to-many class="cn.itcast.vo.Order"/>
            </set>
        </class>
        <!-- 命名查询的方式 -->
        <query name="findAll">
        from Customer 
        </query>
        <!--  这里要写sql语句
        <sql-query>
        
        </sql-query>
        -->
    </hibernate-mapping>
    package cn.itcast.test;
    
    import org.hibernate.LockMode;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import org.junit.Test;
    
    import cn.itcast.utils.HibernateUtils;
    import cn.itcast.vo.Customer;
    
    /**
     * 
     * Hibernate的事务管理:
     * @author zhongzh
     *
     */
    public class HibernateDemo3 {
        @Test
        /*
         * 使用乐观锁解决丢失更新  也需要两个事务同时操作这条记录。
         */
          public void demo6(){
              Session session = HibernateUtils.openSession();
              Transaction tx = session.beginTransaction();
            
              Customer customer = (Customer) session.get(Customer.class, 3);
              customer.setAge(26);
              tx.commit();
              session.close();
          }
        @Test
        /*
         * 使用乐观锁解决丢失更新
         */
          public void demo5(){
              Session session = HibernateUtils.openSession();
              Transaction tx = session.beginTransaction();
            
              Customer customer =  (Customer) session.get(Customer.class, 3);
              customer.setCname("沈明贞");
              
              tx.commit();
              session.close();
          }
        @Test
        /*
         * 使用悲观锁解决丢失更新  底层执行的是同一个,只不过事务不一样而已
         */
          public void demo4(){
              Session session = HibernateUtils.openSession();
              Transaction tx = session.beginTransaction();
            // 使用悲观锁(排它锁)
                @SuppressWarnings("deprecation")
                Customer customer = (Customer) session.get(Customer.class, 3, LockMode.UPGRADE);
                customer.setAge(32);
              tx.commit();
              session.close();
          }
        @Test
        /*
         * 使用悲观锁解决丢失更新
         */
        public void demo3(){
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
            // 使用悲观锁(排它锁)
            @SuppressWarnings("deprecation")
            Customer customer = (Customer) session.get(Customer.class, 3, LockMode.UPGRADE);
            customer.setCname("沈明贞");
            tx.commit();
            session.close();
        }
        
          @Test
          /*
           * 
           * 丢失更新的产生
           * 
           */
          public void demo2(){
              Session session = HibernateUtils.openSession();
              Transaction tx = session.beginTransaction();
              Customer customer =   (Customer) session.get(Customer.class, 3);
             //再有一个事务去更新customer的年龄
              customer.setAge(30);//持久态对象不用手动调update都可以完成更新
              
              //System.out.println(customer);
              tx.commit();
              session.close();
          }
      @Test
      /*
       * 
       * 丢失更新的产生
       * 
       */
      public void demo1(){
          Session session = HibernateUtils.openSession();
          Transaction tx = session.beginTransaction();
          Customer customer =   (Customer) session.get(Customer.class, 3);
          //假设就有一个事务在更新这个customer的名称
          customer.setCname("沈明贞");
          
          //System.out.println(customer);
          tx.commit();
          session.close();
      }
    }
  • 相关阅读:
    6种GET和POST请求发送方法
    微信公众平台开发框架推荐
    PHPExcel内存泄漏问题
    7个鲜为人知却超实用的PHP函数
    java调用C程序
    php AES加密 对应Java SHA1PRNG方式加密
    yii插入数据库防并发
    PHPUnit测试
    yii2源码学习笔记(二十)
    yii2源码学习笔记(十九)
  • 原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6702654.html
Copyright © 2020-2023  润新知