zoukankan      html  css  js  c++  java
  • day36 11-Hibernate中的事务:当前线程中的session

    如果你没有同一个session开启事务的话,那它两是一个独立的事务。必须是同一个session才有效。它给我们提供一个本地线程的session。这个session就保证了你是同一个session。其实它底层用的就是ThreadLocal。

    什么是JTA事务?就是你底层操作的时候可能操作的不是同一个数据库。我们这里的保存都往同一个数据库里面保存。user和person都是保存到mysql数据库那不叫JTA事务,如果user保存到mysql数据库,person保存到oracle数据库,那这种事务的绑定用的是JTA这种事务,就是你操作的都不是同一个数据库了。SessionFactory.getCurrentSession()直接把当前线程中的session给它拿回去就行。只要是同一个线程就行,同一个线程拿的session肯定是同一个。SessionFactory.getCurrentSession()拿到当前线程绑定的session。只要是一个线程里面得到的都是同一个session。只不过当前线程中的session得配置一个值<property name="hibernate.current_session_context_class">thread</property>才可以使用。

    package cn.itcast.utils;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    /**
     * Hibernate抽取工具类
     * @author 姜涛
     *
     */
    public class HibernateUtils {
        private static Configuration configuration;
        private static SessionFactory sessionFactory;
        
        static{
            configuration = new Configuration().configure();
            sessionFactory = configuration.buildSessionFactory();
        }
        
        public static Session openSession(){
            return sessionFactory.openSession();
        }
        public static Session getCurrentSession(){
            return sessionFactory.getCurrentSession();//把当前线程中的session拿回去就行
        }
        public static void main(String[] args) {
            openSession();
        }
    }
    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
        /*
         * 当前线程这个绑定的session的使用
         * 
         */
        public void demo8(){
            Session session = HibernateUtils.getCurrentSession();
            Transaction tx = session.beginTransaction();
            
            Customer customer = new Customer();
            customer.setCname("张三");
            customer.setAge(28);
            session.save(customer);
            
            tx.commit();
            //session.close();
            
        }
        @Test
        /*
         * 事务通常在service层开启.session在DAO层.
         *   * 事务开启由session开启.
         * 
         */
        public void demo7(){//hibernate做的是dao层的代码
            Session session1 = HibernateUtils.openSession();
            Session session2 = HibernateUtils.openSession();
            System.out.println(session1==session2);
            Session session3 = HibernateUtils.getCurrentSession();
            Session session4 = HibernateUtils.getCurrentSession();
            System.out.println(session3 == session4);
        }
        @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();
      }
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    
    <hibernate-configuration>
    <session-factory>
        <!-- 必须去配置的属性 -->
        <!-- 配置数据库连接的基本信息: -->
        <property name="hibernate.connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
        <property name="hibernate.connection.url"><!-- 连接的数据库是hibernate3_day02 -->
            jdbc:mysql:///hibernate3_day03
        </property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password"></property>
        <!-- Hibernate的方言 -->
        <!-- 生成底层SQL不同的 -->
        <property name="hibernate.dialect">
            org.hibernate.dialect.MySQLDialect
        </property>
    
        <!-- 可选的属性 -->
        <!-- 显示SQL -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化SQL -->
        <property name="hibernate.format_sql">true</property>
    
        <property name="hibernate.connection.autocommit">false</property>
        <!-- hbm:映射 to DDL: create drop alter -->
        <property name="hibernate.hbm2ddl.auto">update</property>
    
        <!-- C3P0连接池设定-->
        <!-- 使用c3po连接池  配置连接池提供的供应商-->
        <property name="connection.provider_class">
            org.hibernate.connection.C3P0ConnectionProvider
        </property>
    
        <!--在连接池中可用的数据库连接的最少数目 -->
        <property name="c3p0.min_size">5</property>
        <!--在连接池中所有数据库连接的最大数目  -->
        <property name="c3p0.max_size">20</property>
        <!--设定数据库连接的过期时间,以秒为单位,
            如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
        <property name="c3p0.timeout">120</property>
        <!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
        <property name="c3p0.idle_test_period">3000</property>
        
        <!-- 
            1-Read uncommited isolation
            2-Read commmitted isolation   oracle默认是2
            4-Repeatable read isolation   mysql默认是4
            8-Serializable isolation
         -->
        <property name="hibernate.connection.isiolation">4</property>
        
        <!-- 通知Hibernate加载那些映射文件 -->
        <!--     <mapping resource="cn/itcast/hibernate3/demo1/Book.hbm.xml" />
            <mapping resource="cn/itcast/hibernate3/demo2/Customer.hbm.xml" />
            <mapping resource="cn/itcast/hibernate3/demo2/Order.hbm.xml" />
            <mapping resource="cn/itcast/hibernate3/demo1/Book.hbm.xml" /> -->
        <!-- 使用当前线程中的session -->
            <property name="hibernate.current_session_context_class">thread</property><!-- 代表了当前线程中的session -->
        <!-- 把映射文件中的这几个都拿掉  重新把它引入  -->
        <mapping resource="cn/itcast/vo/Customer.hbm.xml" />
        <mapping resource="cn/itcast/vo/Order.hbm.xml" />
    
    
    </session-factory>
    </hibernate-configuration>
  • 相关阅读:
    关于Web应用开发流程的总结
    package.json的所有配置项及其用法,你都熟悉么
    curl 命令行工具的使用及命令参数说明
    pytest插件探索——hook开发
    浅探前端图片优化
    使用Flask构建一个Web应用
    原生的js实现jsonp的跨域封装
    CSS定位之BFC背后的神奇原理
    webview错误
    Android 中的webview
  • 原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6703751.html
Copyright © 2011-2022 走看看