关于在使用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的生命周期

Hibernatejava对象的三种状态:

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方法的用法的更多相关文章

  1. 分析Hibernate的事务处理机制

    Hibernate是对JDBC的轻量级对象封装,Hibernate本身是不具备Transaction处理功能的,Hibernate的 Transaction实际上是底层的JDBC Transactio ...

  2. J2EE进阶(八)Hibernate与延迟加载机制探究

    Hibernate与延迟加载机制探究 前言 Hibernate对象关系映射提供延迟的与非延迟的对象初始化.非延迟加载在读取一个对象的时候会将与这个对象所有相关的其他对象一起读取出来.这有时会导致成百的 ...

  3. java框架篇---hibernate之缓存机制

    一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...

  4. atitit.spring hibernate的事务机制 spring不能保存对象的解决

    atitit.spring hibernate的事务机制 spring不能保存对象的解决 sessionFactory.openSession() 不能..log黑头马sql语言.. sessionF ...

  5. Hibernate学习---缓存机制

    前言:这些天学习效率比较慢,可能是手头的事情比较多,所以学习进度比较慢. 在之前的Hibernate学习中,我们无论是CURD,对单表查询还是检索优化,我们好像都离不开session,session我 ...

  6. hibernate 的缓存机制

    这是面试中经常问到的一个问题,楼主可以按照我的思路回答,准你回答得很完美,首先说下Hibernate缓存的作用(即为什么要用缓存机制),然后再具体说说Hibernate中缓存的分类情况,最后可以举个具 ...

  7. Hibernate中evict方法和clear方法说明

    Hibernate中evict方法和clear方法说明 先创建一个对象,然后调用session.save方法,然后调用evict方法把该对象清除出缓存,最后提交事务.结果报错: Exception i ...

  8. Hibernate 所有缓存机制详解

    hibernate提供的一级缓存 hibernate是一个线程对应一个session,一个线程可以看成一个用户.也就是说session级缓存(一级缓存)只能给一个线程用,别的线程用不了,一级缓存就是和 ...

  9. Hibernate笔记——缓存机制详细分析

    原文:http://www.cnblogs.com/xiaoluo501395377/p/3377604.html ========================================== ...

随机推荐

  1. ecshop收货地址货到付款修改

    用户选择某些地址时,支付方式里则可以依据此地址来对货到付款选项进行显示或隐藏.目前仅与顺丰合作,以顺丰提供的数据为准. 使用到的数据库分别如下: ecs_region//地方数据,PRIMARY KE ...

  2. 什么是Css Hack?ie6,7,8的hack分别是什么?

    针对不同的浏览器写不同的CSS code的过程,就是CSS hack. 示例如下: 1 2 3 4 5 6 7 8 9 10 11 12 #test       { width:300px; heig ...

  3. 数据结构与算法(c++)——查找二叉树与中序遍历

    查找树ADT--查找二叉树 定义:对于树中的每个节点X,它的左子树中的所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项. 现在给出字段和方法定义(BinarySearchTree.h) # ...

  4. 使用react-router setRouteLeaveHook的钩子函数

    今天在使用react-router setRouteLeaveHook的钩子函数,不知道怎么实验就是成功.最后功夫不负有心人,终于让我找到使用setRouteLeaveHook的方法了 1.我在网络上 ...

  5. 【LeetCode】118. Pascal's Triangle

    题目: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,R ...

  6. ionic搭建与基础

    ionic搭建与基础 一.环境搭建 安装 npm install -g cordova npm install -g ionic 创建 项目 ionic start MyProject blank i ...

  7. 致命错误:mysql/cli 目录 #include "mysql/client_plugin.h"

    居然说没有mysql.h这个文件,可是我确实安装了mysql了啊.......  原来是缺少libmysqlclient-dev,OK安装就是了 ubuntu下  :  audo apt-get in ...

  8. PostgreSQL 使用 PreparedStatement 导致查询慢的分析

    实验环境: DB is PostgreSQL version 8.2.15 JDK1.8 测试一 使用JDBC查询一个SQL: public static void test1(String url, ...

  9. 【原创】无线破解Aircrack-ng套件详解--airmon-ng与airodump-ng

    一:Aircrack-ng详解 1.1 Aircrack-ng概述 Aircrack-ng是一款用于破解无线802.11WEP及WPA-PSK加密的工具,该工具在2005年11月之前名字是Aircra ...

  10. Linux配置LNMP环境(三)配置MySQL

    1.执行代码:cd /usr/local/rsc下载MySQL,我是从搜狐镜像上下载的:http://mirrors.sohu.com/mysql/MySQL-5.5/,我下载的是64位(注意)的,下 ...