关于在使用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. php访问数据库$result=$mysql_qurey('')判断是否是空值

    在访问数据库后得到result值,前提是$relust为true,就是没有发生错误连接情况,但是查询的条件由于不满足导致返回值为空,此时判断就不能用!来决定是否有返回数据了,经过书籍搜索,用resul ...

  2. WPF的一些感悟

    第一天在博客园写东西,只写一些自己对WPF稚嫩的理解和感悟. 1.Code Snippet代码简写工具 可以创建自己的代码模板管理器——>>>工具菜单,代码片段管理器 考出现有的+更 ...

  3. JavaScript浮点运算的问题 (乘法)

    <script type="text/javascript"> var get_b_val_final=accMul(get_b_val,100)+"%&qu ...

  4. jquery中div悬浮嵌套按钮效果

    <div class="btn_sure_cai" style="margin-left: 0px;" onmouseover="show_hi ...

  5. yii2 入口文件 提示syntax error, unexpected T_OBJECT_OPERATOR

    PHP Version 5.3.3 原因是php的安装版本太低

  6. Codeforces 818B Permutation Game

    首先看一下题目 B. Permutation Game time limit per test 1 second memory limit per test 256 megabytes input s ...

  7. Vijos 1011 清帝之惑之顺治 记忆录式的动态规划(记忆化搜索)

    背景 顺治帝福临,是清朝入关后的第一位皇帝.他是皇太极的第九子,生于崇德三年(1638)崇德八年八月二ten+six日在沈阳即位,改元顺治,在位18年.卒于顺治十八年(1661),终24岁. 顺治即位 ...

  8. AppDelegate减负之常用三方封装 - 友盟分享 / 三方登录篇

    之前完成了 AppDelegate减负之常用三方封装 - 友盟推送篇: http://www.cnblogs.com/zhouxihi/p/7113511.html 今天接着来完成 - 友盟分享和三方 ...

  9. 在Visual Studio 2017中使用Asp.Net Core构建Angular4应用程序

    前言 Visual Studio 2017已经发布了很久了.做为集成了Asp.Net Core 1.1的地表最强IDE工具,越来越受.NET系的开发人员追捧. 随着Google Angular4的发布 ...

  10. vsftpd3.0之匿名用户配置

    有时候工作中为了方便上传下载文件,又不想在系统中添加用户并为用户创建密码,这时候就可以用匿名用户方式搭建FTP服务器,当然安全性我们不说,今天就为实现这么个简单而粗爆的FTP服务器,来看看都需要哪些配 ...