当前位置: 首页 > news >正文

hibernate中的Session.flush()

 

转自: http://www.blogjava.net/ywj-316/archive/2009/11/03/300930.html

session flush测试:

session flush方法主要做了两件事:
1 清理缓存
2 执行sql(不是提交事务)

session在什么情况下执行flush
1 默认在事务提交时
2 显式的调用flush
3 在执行查询前,如:iterate

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

 

hibernate执行的顺序如下,

(1)生成一个事务的对象,并标记当前的Session处于事务状态(注:此时并未启动数据库级事务)。 
(2)应用使用s.save保存对象,这个时候Session将这个对象放入entityEntries,用来标记对象已经和当前的会

话建立了关联,由于应用对对象做了保存的操作,Session还要在insertions中登记应用的这个插入行为(行为包括:对象引用、对象 id、Session、持久化处理类)。 
(3)s.evict将对象从s会话中拆离,这时s会从entityEntries中将这个对象移出。 
(4)事务提交,需要将所有缓存flush入数据库,Session启动一个事务,并按照insert,update,……,delete的顺序

提交所有之前登记的操作(注意:所有insert执行完毕后才会执行update,这里的特殊处理也可能会将你的程序搞

得一团糟,如需要控制操作的执行顺序,要善于使用flush),现在对象不在entityEntries中,但在执行insert的行

为时只需要访问insertions就足够了,所以此时不会有任何的异常。异常出现在插入后通知Session该对象已经插入

完毕这个步骤上,这个步骤中需要将entityEntries中对象的existsInDatabase标志置为true,由于对象并不存在于 entityEntries中,此时Hibernate就认为insertions和entityEntries可能因为线程安全的问题产生了不同步(也 不知道Hibernate的开发者是否考虑到例子中的处理方式,如果没有的话,这也许算是一个bug吧),于是一个 net.sf.hibernate.AssertionFailure就被抛出,程序终止

 

session.evict(obj),会把指定的缓冲对象进行清除 
session.clear(),把缓冲区内的全部对象清除,但不包括操作中的对象

 

------------------------------------------------------------------------

  <id name="id">
   <generator class="uuid"/>
  </id>
  因为id的主键生成策略采用的是uuid,所以调用完save后,只是将user对象纳入到session的管理
  不会发出insert语句,但是id已经生成,session中existsInDatebase状态为false
  session.save(user);
  调用flush,hibernate会清理缓存,执行sql
  如果数据库的隔离级别为提交读,那么我们可以看到flush过的数据
  并且session中existsInDatebase状态变为true
  session.flush();
  默认情况下commit操作会先执行者flush清理缓存,所以不用显式的调用flush
  commit后数据无法回滚
  session.getTransaction().commit();
  
  <id name="id">
   <generator class="native"/>
  </id>
  如果id的主键生成策略采用的是native,调用save(user)时会发出insert语句,返回由数据库生成的id,
  user对象纳入到session的管理,session中existsInDatebase状态为true
-----------------------------------------------------------------
  <id name="id">
   <generator class="uuid"/>
  </id>
  session.save(user);
  将user对象从session中逐出,即session的EntiryEntries属性中逐出
  session.evict(user);//清理缓存
  无法成功提交,因为hibernate在清理缓存时,在session的insertions集合中取出user对象进行insert操作后
  需要更新entityEntries属性中的existsnDatabase为true,而我们采用evict已经将user从session中
  逐出了,所以找不到相关数据,无法更新,抛出异常
  session.getTransaction().commit();
----------------------------------------------------------------
  <id name="id">
   <generator class="uuid"/>
  </id>
  session.save(user);
  flush后hibernate会清理缓存,会将user对象保存到数据库中,将session中的insertions中的user
  清除,并且设置session中existsInDatabase的状态为true
  session.flush(user);
  将user对象从session中逐出,即session的EntityEntries属性中逐出
  session.evict(user);//清理缓存
  可以成功提交,因为hibernate在清理缓存时,在session的insertions集合中无法找到user对象
  所以就不会发出insert语句,也不会更新session中的existsInDatabase的状态
  session.getTransaction().commit();
-----------------------------------------------------------------
  <id name="id">
   <generator class="native"/>
  </id>
  session.save(user);
  将user对象从session中逐出,即session的EntityEntries属性中逐出
  session.evict(user);//清理缓存
  可以成功提交,因为hibernate在清理缓存时,在session的insertions集合中无法找到user对象
  所以就不会发出insert语句,也不会更新session中的existsInDatabase的状态
  session.getTransaction().commit();
-----------------------------------------------------------------
    <id name="id">
   <generator class="assigned"/>
  </id>
  session.save(user);
  user.setName("张三");
  session.update(user);
  User user2=new User();
  user2.setId("003");
  user2.setName("李四");
  session.getTransaction().commit();
  结果:
  insert into ...
  insert into ...
  update t_user ...
  hibernate按照save(insert),update,delete顺序提交相关的操作
-----------------------------------------------------------------
   <id name="id">
   <generator class="assigned"/>
  </id>
  session.save(user);
  user.setName("张三");
  session.update(user);
  因为我们在session.update(user)后执行了flush,所以在以commit清理缓存时执行flush前的sql就不会发出.
  session.flush();//在这里flush操作就可以了
  
  User user2=new User();
  user2.setId("003");
  user2.setName("李四");
  session.getTransaction().commit();
  结果:
  insert into ...
  update t_user ...
  insert into ...
  按照我们想要顺序save(insert),update,save(insert)的顺序提交操作
-----------------------------------------------------------------

 

相关文章:

  • hibernate的lazy机制
  • hibernate的lazy策略使用总结
  • springmvc-spring-mybatis实现最简单的登录验证
  • hibernate 的lazy策略存在的问题
  • hibernate中的悲观锁和乐观锁
  • hibernate的查询缓存机制
  • 洛谷 P1521 求逆序对
  • java静态方法的继承
  • Linux内核之内存管理完全剖析
  • 《java与模式》学习系列——简单工厂模式
  • 马尔科夫随机过程的理解
  • 《java与模式》学习系列——工厂模式
  • String a = new String(b);到底是几个对象
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • 《java与模式》学习系列——抽象工厂模式
  • [译] React v16.8: 含有Hooks的版本
  • 03Go 类型总结
  • Android单元测试 - 几个重要问题
  • CentOS7 安装JDK
  • Cookie 在前端中的实践
  • create-react-app做的留言板
  • git 常用命令
  • HashMap ConcurrentHashMap
  • java8-模拟hadoop
  • Mysql5.6主从复制
  • node入门
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • springboot_database项目介绍
  • STAR法则
  • Vim 折腾记
  • 包装类对象
  • 给初学者:JavaScript 中数组操作注意点
  • 新手搭建网站的主要流程
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • ​iOS实时查看App运行日志
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (arch)linux 转换文件编码格式
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (离散数学)逻辑连接词
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • *p++,*(p++),*++p,(*p)++区别?
  • .cn根服务器被攻击之后
  • .equals()到底是什么意思?
  • .net framework 4.0中如何 输出 form 的name属性。