hibernate学习笔记第8讲-session_flush-数据库隔离级别

 

Session  flush:

默认在commit之前执行flush

Session  flush方法主要做了两件事

           1清理缓存

           2 执行sql

Session flush 在什么时候执行:

           1 默认在事务提交commit

           2, 显示调用。

     3 在执行查询前,如 iterate

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

 

 

数据库隔离级别:


 

大部分数据库采用 read commited

Mysql 默认采用repeatable read

脏读:事务还没提交,就可以读到,此时如果事务回滚,就出现脏数据。

不可重复读:第一次读的为A,之后另一个人修改为B,此时再读,显示为B,与第一次读的不同,出现不可重复读。解决办法:在第一次读的时候锁住该条记录,别人修改不了。

幻读:第一次查询读出5条数据,之后别人添加记录,当第二次读的时候,变成10条记录。此时为幻读。

 

 

/**

 * 测试uuid主键生成策略

 */

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会清理缓存,执行sql

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

                    //并且sessionexistsInDatebase状态为true

                    session.flush();

                   

                    //提交事务

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

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

                    tx.commit();

 

 

/**

 * 测试native主键生成策略

 */

 

tx = session.beginTransaction();

 

                    User2 user = new User2();

 

                    user.setPassword("123");

                    user.setCreateTime(new Date());

                    user.setExpireTime(new Date());

                   

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

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

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

                    session.save(user);

                    tx.commit();

 

/**

 * 测试uuid主键生成策略, evict()

 */

 

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

 

 

/**

 * 测试uuid主键生成策略,解决evict()

 */

 

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

/**

 * 测试native主键生成策略,evict()

 */

 

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

 

/**

 * 测试assigned主键生成策略,执行sql顺序

 *

 */

 

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

 

/**

 * 测试assigned主键生成策略,执行sql顺序

 *

 */

 

tx = session.beginTransaction();

                    User3 user = new User3();

                    user.setId("003");

                    user.setName("张三");

                   

                    session.save(user);

                   

                    user.setName("王五");

                    session.update(user);

                   

                    session.flush();

                   

                    User3 user3 = new User3();

                    user3.setId("004");

                    user3.setName("李四");

                    session.save(user3);

                   

                    //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 (?, ?, ?, ?, ?)

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

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

                    tx.commit();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值