您的位置:首页 > 其它

09hibernate_session_flush

2012-08-03 18:06 288 查看
session flush测试:

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

* 清理缓存

* 执行sql

session在什么情况下执行flush

* 默认在事务提交时

* 显示的调用flush

* 在执行查询前,如:iterate

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

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已经生成,session中existsInDatebase状态为false

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

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

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

//并且session中existsInDatebase状态为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的管理,修改了session中existsInDatebase状态为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:先save后evict:抛出异常: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已经生成,session中existsInDatebase状态为false

session.save(user);

//将user对象从session中逐出,即session的EntityEntries属性中逐出

session.evict(user);

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

//需要更新entityEntries属性中的existsInDatabase为true,而我们采用evict已经将user从session的entityEntries

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

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),update、delete顺序提交相关操作

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:先save后flush再evict[注意使用的是每一张表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已经生成,session中existsInDatebase状态为false

session.save(user);

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

//清除,并且设置session中existsInDatebase的状态为true

session.flush();

//将user对象从session中逐出,即session的EntityEntries属性中逐出

session.evict(user);

//可以成功提交,因为hibernate在清理缓存时,在session的insertions集合中无法找到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的管理,修改了session中existsInDatebase状态为true

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

session.save(user);

//将user对象从session中逐出,即session的EntityEntries属性中逐出

session.evict(user);

//可以成功提交,因为hibernate在清理缓存时,在session的insertions集合中无法找到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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: