网站首页 > 技术教程 正文
关于在使用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的特殊处理机制,虽然不建议使用此方法,但是在一些复杂的事务处理过程中,加入此方法虽然会破坏事务的一个提交的完整性,但是可以规避一些不可预见的异常情况!
猜你喜欢
- 2024-11-05 恐高症患者 大众CC改装HellaFlush风格
- 2024-11-05 Redis缓存:redis 数据库管理(redis数据库缓存机制)
- 2024-11-05 空气悬架上身 奥迪S7改HellaFlush风格
- 2024-11-05 HellaFlush风格 大众高尔夫改装方案
- 2024-11-05 年轻的老虫子 老款大众甲壳虫hellaflush潮改装
- 2024-11-05 据说这种“外八”改装风格 许多车主都喜欢
- 2024-11-05 李洋分享奥迪Q5改装AIRBFT气动避震品牌优势
- 2024-11-05 ctx.writeAndFlush(protocol).sync()是什么功能
- 2024-11-05 AIRBFT气动避震工厂李洋讲述大众迈腾旅行版为什么都改装低趴
- 2024-11-05 图解MySQL(5)-Buffer Pool的flush链表
你 发表评论:
欢迎- 最近发表
-
- Win11学院:如何在Windows 11上使用WSL安装Ubuntu
- linux移植(Linux移植freemodbus)
- 独家解读:Win10预览版9879为何无法识别硬盘
- 基于Linux系统的本地Yum源搭建与配置(ISO方式、RPM方式)
- Docker镜像瘦身(docker 减小镜像大小)
- 在linux上安装ollama(linux安装locale)
- 渗透测试系统Kali推出Docker镜像(kali linux渗透测试技术详解pdf)
- Linux环境中部署Harbor私有镜像仓库
- linux之间传文件命令之Rsync傻瓜式教程
- 解决ollama在linux中安装或升级时,通过国内镜像缩短安装时长
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)
本文暂时没有评论,来添加一个吧(●'◡'●)