zoukankan      html  css  js  c++  java
  • 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();
      }
    }
  • 相关阅读:
    什么是ORM
    ORM优缺点
    Azure 中快速搭建 FTPS 服务
    连接到 Azure 上的 SQL Server 虚拟机(经典部署)
    在 Azure 虚拟机中配置 Always On 可用性组(经典)
    SQL Server 2014 虚拟机的自动备份 (Resource Manager)
    Azure 虚拟机上的 SQL Server 常见问题
    排查在 Azure 中新建 Windows 虚拟机时遇到的经典部署问题
    上传通用化 VHD 并使用它在 Azure 中创建新 VM
    排查在 Azure 中新建 Windows VM 时遇到的部署问题
  • 原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6702654.html
Copyright © 2011-2022 走看看