zoukankan      html  css  js  c++  java
  • 09hibernate_session_flush

    session flush测试:

     

    session flush方法主要做了两件事:

        * 清理缓存

        * 执行sql

       

    session在什么情况下执行flush

        * 默认在事务提交时

        * 显示的调用flush

        * 在执行查询前,如:iterate

       

    hibernate按照save(insert),updatedelete顺序提交相关操作

     

     

    uuid:create table t_user1 (user_id varchar(32) not null, name varchar(20) not null unique, password varchar(10) not null, create_time datetime, expire_time datetime, primary key (user_id))

     

    native:create table t_user2 (user_id integer not null auto_increment, name varchar(20) not null unique, password varchar(10) not null, createtime datetime, expiretime datetime, primary key (user_id))

     

    assigned:create table t_user3 (user_id varchar(32) not null, name varchar(255), password varchar(255), create_time datetime, expire_time datetime, primary key (user_id))

     

     

     

     

     

        /**

         * 测试uuid主键生成策略1完成save后不会发出insert语句,直到commitflush时才发insert语句

         */

        publicvoid testSave1() {

           Session session = null;

           Transaction tx = null;

           try {

               session = HibernateUtils.getSession();

               tx = session.beginTransaction();

     

               User1 user = new User1();

               user.setName("李四3");

               user.setPassword("123");

               user.setCreateTime(new Date());

               user.setExpireTime(new Date());

              

               //因为user的主键生成侧路采用的是uuid,所以调用完成save,只是将user纳入到了session的管理

               //不会发出insert语句,但是id已经生成,sessionexistsInDatebase状态为false

               session.save(user);//save,不发Hibernate: insert into

              

               //调用flushhibernate会清理缓存,执行sql

               //如果数据库的隔离级别设置为:未提交读read uncommitted,那么我们可以看到flush过的数据

               //并且sessionexistsInDatebase状态为true

               session.flush();//Hibernate: insert into

              

               //提交事务

               //commit后数据是无法回滚的

               tx.commit();//默认情况下commit操作会先执行flush清理缓存,所以不用显示的调用flush

           }catch(Exception e) {

               e.printStackTrace();

               tx.rollback();

           }finally {

               HibernateUtils.closeSession(session);

           }

        }

    session.flush();//flush后:发Hibernate: insert into

    Hibernate: insert into t_user1 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

     

     

    没有提交事务前:我们来看一下数据库中有没有记录:

     

    mysql> select @@tx_isolation;

    +-----------------+

    | @@tx_isolation  |

    +-----------------+

    | REPEATABLE-READ |

    +-----------------+

    1 row in set (0.03 sec)

     

    mysql> select * from t_user1;

    Empty set (0.06 sec)

     

    mysql> set  transaction isolation level read uncommitted;

    Query OK, 0 rows affected (0.00 sec)

     

    mysql> select @@tx_isolation;

    +------------------+

    | @@tx_isolation   |

    +------------------+

    | READ-UNCOMMITTED |

    +------------------+

    1 row in set (0.00 sec)

     

    mysql> select * from t_user1;

    +----------------------------------+-------+----------+---------------------+---------------------+

    | user_id                          | name  | password | create_time         | expire_time         |

    +----------------------------------+-------+----------+---------------------+---------------------+

    | 402881e738eb64e20138eb65f3990001 | 李四3 | 123      | 2012-08-03 15:31:55 | 2012-08-03 15:32:02 |

    +----------------------------------+-------+----------+---------------------+---------------------+

    1 row in set (0.00 sec)

     

    /**

         * 测试native主键生成策略:完成save后马上发出insert语句

         */

        publicvoid testSave2() {

           Session session = null;

           Transaction tx = null;

           try {

               session = HibernateUtils.getSession();

               tx = session.beginTransaction();

     

               User2 user = new User2();

               user.setName("猪八戒");

               user.setPassword("123");

               user.setCreateTime(new Date());

               user.setExpireTime(new Date());

              

               //因为user的主键生成策略为native,所以调用session.save后,将执行insert语句,返回有数据库生成的id

               //纳入了session的管理,修改了sessionexistsInDatebase状态为true

               //如果数据库的隔离级别设置为:未提交读read uncommitted,那么我们可以看到save过的数据

               session.save(user);//save,马上发Hibernate: insert into

               tx.commit();

           }catch(Exception e) {

               e.printStackTrace();

               tx.rollback();

           }finally {

               HibernateUtils.closeSession(session);

           }

        }

     

     

    save后,将执行insert语句,返回有数据库生成的id

               //纳入了session的管理,修改了sessionexistsInDatebase状态为true

     

     

     

    mysql> select * from t_user2;

    +---------+--------+----------+---------------------+---------------------+

    | user_id | name   | password | createtime          | expiretime          |

    +---------+--------+----------+---------------------+---------------------+

    |       1 | 猪八戒 | 123      | 2012-08-03 16:09:44 | 2012-08-03 16:09:55 |

    +---------+--------+----------+---------------------+---------------------+

    1 row in set (0.00 sec)

     

    /**

         * 测试uuid主键生成策略2:先saveevict抛出异常:org.hibernate.AssertionFailure: possible nonthreadsafe access to session

     

         */

        publicvoid testSave3() {

           Session session = null;

           Transaction tx = null;

           try {

               session = HibernateUtils.getSession();

               tx = session.beginTransaction();

     

               User1 user = new User1();

               user.setName("王五");

               user.setPassword("123");

               user.setCreateTime(new Date());

               user.setExpireTime(new Date());

              

               //因为user的主键生成侧路采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理

               //不会发出insert语句,但是id已经生成,sessionexistsInDatebase状态为false

               session.save(user);

              

               //user对象从session中逐出,即sessionEntityEntries属性中逐出

               session.evict(user);

              

               //无法成功提交,因为hibernate在清理缓存时,在sessioninsertions集合中取出user对象进行insert操作后

               //需要更新entityEntries属性中的existsInDatabasetrue,而我们采用evict已经将usersessionentityEntries

               //中逐出了,所以找不到相关数据,无法更新,抛出异常

               tx.commit();

           }catch(Exception e) {

               e.printStackTrace();

               tx.rollback();

           }finally {

               HibernateUtils.closeSession(session);

           }

        }

     

     

    Save后:

     

     

     

    Evict后:

     

     

    org.hibernate.AssertionFailure: possible nonthreadsafe access to session

    /**

         * 测试assigned主键生成策略:[注意使用的是每一张表t_user3]

         *

         */

        publicvoid testSave6() {

           Session session = null;

           Transaction tx = null;

           try {

               session = HibernateUtils.getSession();

               tx = session.beginTransaction();

     

               User3 user = new User3();

               user.setId("001");

               user.setName("张三");

              

               session.save(user);[U1] 

              

               user.setName("王五");

               session.update[U2] (user);

              

               User3 user3 = new User3();

               user3.setId("002");

               user3.setName("李四");

               session.save[U3] (user3);

              

               //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

               //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

               //Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?

               //hibernate按照save(insert),updatedelete顺序提交相关操作

               tx.commit();

           }catch(Exception e) {

               e.printStackTrace();

               tx.rollback();

           }finally {

               HibernateUtils.closeSession(session);

           }

        }  

    //注意:hibernate按照save(insert),updatedelete顺序提交相关操作

    /**

         * 测试assigned主键生成策略:[注意使用的是每一张表t_user3] hibernate按照save(insert),updatedelete顺序提交相关操作

         *

         */

        publicvoid testSave6() {

           Session session = null;

           Transaction tx = null;

           try {

               session = HibernateUtils.getSession();

               tx = session.beginTransaction();

     

               User3 user = new User3();

               user.setId("001");

               user.setName("张三");

              

               session.save(user);

              

               user.setName("王五");

               session.update(user);

              

               User3 user3 = new User3();

               user3.setId("002");

               user3.setName("李四");

               session.save(user3);

               //注意:hibernate按照save(insert),updatedelete顺序提交相关操作

               //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

               //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

               //Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?

              

               tx.commit();

           }catch(Exception e) {

               e.printStackTrace();

               tx.rollback();

           }finally {

               HibernateUtils.closeSession(session);

           }

        }  

    Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

    Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

    Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?

     

    mysql> select * from t_user3;

    +---------+------+----------+-------------+-------------+

    | user_id | name | password | create_time | expire_time |

    +---------+------+----------+-------------+-------------+

    | 001     | 王五 | NULL     | NULL        | NULL        |

    | 002     | 李四 | NULL     | NULL        | NULL        |

    +---------+------+----------+-------------+-------------+

    2 rows in set (0.00 sec)

    /**

         * 测试assigned主键生成策略:[注意使用的是每一张表t_user3]显示调用flush后,sql会按照我们的意愿执行

         *

         */

        publicvoid testSave7() {

           Session session = null;

           Transaction tx = null;

           try {

               session = HibernateUtils.getSession();

               tx = session.beginTransaction();

     

               User3 user = new User3();

               user.setId("003");

               user.setName("张三");

              

               session.save(user);

              

               user.setName("王五");

               session.update(user);

               //因为我们在session.udpate(user)后执行了flush,所以在清理缓存时执行flush前的sql不会生成

               //sql会按照我们的意愿执行

               session.flush();

              

               User3 user3 = new User3();

               user3.setId("004");

               user3.setName("李四");

               session.save(user3);

              

               tx.commit();

           }catch(Exception e) {

               e.printStackTrace();

               tx.rollback();

           }finally {

               HibernateUtils.closeSession(session);

           }

        }     

    }

    //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

    //Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?

    //Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

     

    Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

    Hibernate: update t_user3 set name=?, password=?, create_time=?, expire_time=? where user_id=?

    Hibernate: insert into t_user3 (name, password, create_time, expire_time, user_id) values (?, ?, ?, ?, ?)

     

    mysql> select * from t_user3;

    +---------+------+----------+-------------+-------------+

    | user_id | name | password | create_time | expire_time |

    +---------+------+----------+-------------+-------------+

    | 001     | 王五 | NULL     | NULL        | NULL        |

    | 002     | 李四 | NULL     | NULL        | NULL        |

    | 003     | 王五 | NULL     | NULL        | NULL        |

    | 004     | 李四 | NULL     | NULL        | NULL        |

    +---------+------+----------+-------------+-------------+

    4 rows in set (0.00 sec)

     

    不明白以下两个程序:

    /**

         * 测试uuid主键生成策略3:saveflushevict[注意使用的是每一张表t_user1]

         */

        publicvoid testSave4() {

           Session session = null;

           Transaction tx = null;

           try {

               session = HibernateUtils.getSession();

               tx = session.beginTransaction();

     

               User1 user = new User1();

               user.setName("王五");

               user.setPassword("123");

               user.setCreateTime(new Date());

               user.setExpireTime(new Date());

              

               //因为user的主键生成侧路采用的是uuid,所以调用完成save后,只是将user纳入到了session的管理

               //不会发出insert语句,但是id已经生成,sessionexistsInDatebase状态为false

               session.save(user);

              

               //flushhibernate会清理缓存,会将user对象保存到数据库中,将session中的insertions中的user对象

               //清除,并且设置sessionexistsInDatebase的状态为true

               session.flush();

              

               //user对象从session中逐出,即sessionEntityEntries属性中逐出

               session.evict(user);

              

               //可以成功提交,因为hibernate在清理缓存时,在sessioninsertions集合中无法找到user对象

               //所以就不会发出insert语句[U4] ,也不会更新session中的existsInDatabase的状态

               tx.commit();

           }catch(Exception e) {

               e.printStackTrace();

               tx.rollback();

           }finally {

               HibernateUtils.closeSession(session);

           }

        }

       

       

     

    mysql> select * from t_user1;

    +----------------------------------+---------+----------+---------------------+---------------------+

    | user_id                          | name    | password | create_time         | expire_time         |

    +----------------------------------+---------+----------+---------------------+---------------------+

    | 402881e738ebdb9f0138ebdcab230001 | 王五    | 123      | 2012-08-03 17:41:34 | 2012-08-03 17:41:35 |

    | 402881e738ebe0960138ebe098920001 | 王五1   | 123      | 2012-08-03 17:46:01 | 2012-08-03 17:46:01 |

    | 402881e738ebe5dc0138ebe5ddc10001 | 王五11  | 123      | 2012-08-03 17:51:46 | 2012-08-03 17:51:46 |

    | 402881e738ebe6d60138ebe6d7b10001 | 王五111 | 123      | 2012-08-03 17:52:50 | 2012-08-03 17:52:50 |

    +----------------------------------+---------+----------+---------------------+---------------------+

    5 rows in set (0.00 sec)

     

    /**

         * 测试native主键生成策略2:[注意使用的是每一张表t_user2]

         */

        publicvoid testSave5() {

           Session session = null;

           Transaction tx = null;

           try {

               session = HibernateUtils.getSession();

               tx = session.beginTransaction();

     

               User2 user = new User2();

               user.setName("张三11");

               user.setPassword("123");

               user.setCreateTime(new Date());

               user.setExpireTime(new Date());

              

               //因为user的主键生成策略为native,所以调用session.save后,将执行insert语句,返回有数据库生成的id

               //纳入了session的管理,修改了sessionexistsInDatebase状态为true

               //如果数据库的隔离级别设置为为提交读,那么我们可以看到save过的数据

               session.save(user);

              

               //user对象从session中逐出,即sessionEntityEntries属性中逐出

               session.evict(user);

              

               //可以成功提交,因为hibernate在清理缓存时,在sessioninsertions集合中无法找到user对象

               //所以就不会发出[U5] insert语句,也不会更新session中的existsInDatabase的状态

               tx.commit();

           }catch(Exception e) {

               e.printStackTrace();

               tx.rollback();

           }finally {

               HibernateUtils.closeSession(session);

           }

        }

     

    mysql> select * from t_user2;

    +---------+---------+----------+---------------------+---------------------+

    | user_id | name    | password | createtime          | expiretime          |

    +---------+---------+----------+---------------------+---------------------+

    |       1 | 猪八戒  | 123      | 2012-08-03 16:09:44 | 2012-08-03 16:09:55 |

    |       2 | 猪八戒2 | 123      | 2012-08-03 16:22:08 | 2012-08-03 16:22:08 |

    |       3 | 张三11  | 123      | 2012-08-03 17:48:34 | 2012-08-03 17:48:35 |

    |       4 | 张三111 | 123      | 2012-08-03 17:51:23 | 2012-08-03 17:51:23 |

    |       5 | 张三1   | 123      | 2012-08-03 17:53:58 | 2012-08-03 17:53:58 |

    +---------+---------+----------+---------------------+---------------------+

    5 rows in set (0.00 sec)


     

     

  • 相关阅读:
    NX二次开发-UF_MODL_ask_angle_tolerance获取建模的角度公差
    NX二次开发-UF_MODL_create_bplane创建有界平面
    NX二次开发-UF_MODL_ask_point_containment获取一个点是在体(面,边)的边界内部,外部,还是边界上
    NX二次开发-UFUN获取相邻面UF_MODL_ask_adjac_faces
    NX二次开发-UFUN链表UF_MODL_create_list等用法
    NX二次开发-UFUN发射线函数UF_MODL_trace_a_ray的用法
    NX二次开发-Ufun C函数例子目录【更新日期2020.7.5】
    NX二次开发-C++time函数计时
    NX二次开发-C++的vector用法
    关于C++里set_intersection(取集合交集)、set_union(取集合并集)、set_difference(取集合差集)等函数的使用总结
  • 原文地址:https://www.cnblogs.com/alamps/p/2622101.html
Copyright © 2011-2022 走看看