Hibernate的事务处理机制和flush方法的用法
关于在使用hibernate在提交事务时常遇到的异常:
an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
net.sf.hibernate.AssertionFailure: possible
nonthreadsafe access to session
其实这个异常一般都是和我们在操作session flush方法和提交事务过程中会抛出的,下面就具体结合session的事务和声明周期来具体分析下,为什么会有这样的异常;
首先来看下,session的生命周期
Hibernate中java对象的三种状态:
1、临时状态(transient):用new语句创建,还没有被持久化,不处于Session的缓存中。
2、持久化状态(persistent):已使用save()或者saveOrUpdate()方法,处于Session的缓存中和数据库表中,生成了自己的Oid标识。
3、游离状态(detached):被持久化,已使用evict(Object),session.close()或者使用clear()清除缓存,不再处于Session的缓存中或不存在数据库表中,但是依然是存在自己的OId标识。
对象的状态转换

从上面的图中我们可以很清楚的明白一个java对象在session中三种状态的转换,
然后在来看看session缓存在什么时候会被清除:
1.当应用程序调用org.hibernate.Transaction的commit()方法的时候,commit()方法先清理缓存,然后再向数据库提交事务。
2.当应用程序显式调用Session的flush()方法的时候,其实这个方法我们几乎很少用到,因为我们一般都是在完成一个事务才去清理缓存,提交数据更改,这样我们直接提交事务就可以。
clear()和evict(Object)的区别:
从参数就可以看出,clear()是会清除整个session中的缓存,evict(Object)是将一个对象从session缓存中清除;
其实在session持久化操作和数据库中之间还有一层对象缓冲区(entityEntries)

Commit():此方法在执行后会更新对象在对象缓存区中的existsInDatabase=true;
Flush():会按save,update,delete顺序执行,把缓存中的数据flush入数据库中,并清空缓存区;
下面几个例子可以充分说明我们异常抛出的情况:
SessionFactory sf = new
Configuration().configure().buildSessionFactory() ;
Session s = sf.openSession();
Person person = new Person();
Transaction tran =
s.beginTransaction(); (1)
s.save(person); (2)(此处同样可以为update
delete)
s.evict(person); (3)
tran.commit(); (4)
s.close();(5)
看上面的代码,再参照下我们的示例图和commit()方法,就可以很明显的发现代码问题的所在,在第四步evict()方法将cat对象从对象缓存区清除,当我们执行commit()方法后,更新对象在缓存区中状态的时候,由于已被清除,就会出现上述断言的异常;
Person person1 = new Person
();
person1.setName(“tom”);
s.save(person1);
person1.setName(“mary”);
s.update(person1);
Person person2 = new Person
();
person2.setName(“tom”);
s.save(person2);
s.flush();
其实在这里我们看这个代码的时候感觉是没问题 ,在这里我们可以参考下刚提到的flush()方法,此方法会按save,update,delete的顺序进行提交事务,所以在这里会抛出主键冲突的异常,解决的办法是在update()操作后面也加入flush();
总的来说,由于flush()的特殊处理机制,虽然不建议使用此方法,但是在一些复杂的事务处理过程中,加入此方法虽然会破坏事务的一个提交的完整性,但是可以规避一些不可预见的异常情况!
Hibernate的事务处理机制和flush方法的用法的更多相关文章
- 分析Hibernate的事务处理机制
Hibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction处理功能的,Hibernate的 Transaction实际上是底层的JDBC Transactio ...
- J2EE进阶(八)Hibernate与延迟加载机制探究
Hibernate与延迟加载机制探究 前言 Hibernate对象关系映射提供延迟的与非延迟的对象初始化.非延迟加载在读取一个对象的时候会将与这个对象所有相关的其他对象一起读取出来.这有时会导致成百的 ...
- java框架篇---hibernate之缓存机制
一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...
- atitit.spring hibernate的事务机制 spring不能保存对象的解决
atitit.spring hibernate的事务机制 spring不能保存对象的解决 sessionFactory.openSession() 不能..log黑头马sql语言.. sessionF ...
- Hibernate学习---缓存机制
前言:这些天学习效率比较慢,可能是手头的事情比较多,所以学习进度比较慢. 在之前的Hibernate学习中,我们无论是CURD,对单表查询还是检索优化,我们好像都离不开session,session我 ...
- hibernate 的缓存机制
这是面试中经常问到的一个问题,楼主可以按照我的思路回答,准你回答得很完美,首先说下Hibernate缓存的作用(即为什么要用缓存机制),然后再具体说说Hibernate中缓存的分类情况,最后可以举个具 ...
- Hibernate中evict方法和clear方法说明
Hibernate中evict方法和clear方法说明 先创建一个对象,然后调用session.save方法,然后调用evict方法把该对象清除出缓存,最后提交事务.结果报错: Exception i ...
- Hibernate 所有缓存机制详解
hibernate提供的一级缓存 hibernate是一个线程对应一个session,一个线程可以看成一个用户.也就是说session级缓存(一级缓存)只能给一个线程用,别的线程用不了,一级缓存就是和 ...
- Hibernate笔记——缓存机制详细分析
原文:http://www.cnblogs.com/xiaoluo501395377/p/3377604.html ========================================== ...
随机推荐
- AppServ安装的一点小麻烦----
好久,没装AppServ了,今天安装过程顺利,但是Apache,服务开启不了,页面也不能访问. 刚开始以为是版本下载错误了,先后换了N个版本,都不行. 在网上搜的过程中,偶然发现,一句话:64位系统, ...
- Linux版微信
一.到github上下载https://github.com/geeeeeeeeek/electronic-wechat/releases下载linux-x64.tar.gz,具体根据操作系统是32位 ...
- gawk的用法
GNU gawk工具的功能是将指定文件中符合指定模式(pattern)的行按指定的动作(action)进行格式化处理 语法:gawk [options] [program] [file-lis ...
- Perl格式化输出
Perl格式化输出 问题阐述 有时我们需要大量的重复数据,使用手工易于出错及比较繁琐.抓取特征,可以使用Perl脚本轻松搞定. 输出数据格式 主要特点 随机数生成 格式化输出 序列递增 Perl脚本 ...
- 用ingress的方式部署jenkins,启动后提示没有下载插件,未解决
[root@node2 .docker]# docker logs 5c3dd117a10dRunning from: /usr/share/jenkins/jenkins.warwebroot: E ...
- 学习 ES6,一篇文章就够了
ES6 简介 ECMAScript 6 简称 ES6,是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了.它的目标是使得 JavaScript 语言可以用来编写复杂的大型应用程 ...
- 【Android Developers Training】 83. 实现高效网络访问来优化下载
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- VMware Mac OS中无法找到适应的分辨率的解决办法
使用VMware安装的Mac OS中,有时在显示器的分辨率中的选择项里面,没有对应显示的分辨率可供选择的时候(无法自适应),可以在虚拟机设置里,显示器中修改强制分辨率.修改过后重启虚拟机,就可以有对应 ...
- 把对象列表转化成json数据格式
package JsonTest; import java.util.ArrayList; import java.util.List; public class test { public stat ...
- Java算法-------无序数组中的最长连续序列---------leetcode128
Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...