博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
09hibernate_session_flush
阅读量:6690 次
发布时间:2019-06-25

本文共 12346 字,大约阅读时间需要 41 分钟。

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); 

          

           user.setName("王五");

           session.update (user);

          

           User3 user3 = new User3();

           user3.setId("002");

           user3.setName("李四");

           session.save (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语句 ,也不会更新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对象

           //所以就不会发出 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)


 

 

你可能感兴趣的文章
推荐的PHP编码规范
查看>>
Gartner报告:东方金信进入Hadoop世界厂商名录
查看>>
Python_(1)数据类型及其常见使用方法(图文)
查看>>
如何查看WWN号
查看>>
主页被劫持问题
查看>>
linux中awk学习小结
查看>>
WCF分布式开发常见错误(23):the fact that the server certificate isn't configured with HTTP.SYS...
查看>>
第一个Indigo Service
查看>>
《Pro ASP.NET MVC 3 Framework》学习笔记之三十二 【无入侵的Ajax】
查看>>
监听启动报TNS-12537、TNS-12560错误
查看>>
XXX管理平台系统——项目教训
查看>>
会写代码的项目经理
查看>>
通过Lua解释器来扩展丰富nginx功能,实现复杂业务的处理
查看>>
禁用WPF窗体的最大化按钮
查看>>
玩转React样式
查看>>
TinyHttpd中sockaddr与struct sockaddr_in的区别
查看>>
嘉峪关市与甘肃省广电网络公司对接智慧城市建设项目
查看>>
PostgreSQL 收缩膨胀表或索引 - pg_squeeze or pg_repack
查看>>
代码实现从某个表中查询数据插入到另一个表中
查看>>
提高代码质量-工具篇
查看>>