博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate的SQL执行顺序引发的血案
阅读量:7039 次
发布时间:2019-06-28

本文共 1465 字,大约阅读时间需要 4 分钟。

hot3.png

问题起源于代码中对某个对象的处理逻辑,当发现该对象的某些属性变化时,先将原数据删除,再插入一个新对象,由于使用了Spring+Hibernate的组合,很容易写出如下代码:

//从数据库中读取原数据Role entity = hibernateTemplate.load(ID);//将数据复制到新对象上Role newEntity = new Role();BeanCopier.copy(entity, newEntity);//删除原数据hibernateTemplate.delete(entity);//保存新数据hibernateTemplate.save(entity);
然而这段代码在执行时却失败了,程序抛出:DataIntegrityViolationException异常,日志显示如下错误:
SQL Error: 1062, SQLState: 23000Duplicate entry 'demo' for key 'IDX_ROLE_NAME'
即数据插入数据库时失败了,原因是触发了唯一性约束。经反复核实,数据库中数据没有问题,不是其他数据导致的,从代码逻辑上讲,这段代码先删后插也没有任何问题,在一个事务当中也没有什么脏读的问题, 这就搞笑了,问题到底出在哪呢???
打开Hibernate的SQL输出,还原最真实的SQL语句,终于找到了答案,输入日志如下:
Hibernate:     /* insert com.litt.cidp.system.po.Role        */ insert         into            role            (ROLE_NAME, STATUS, REMARK)         values            (?, ?, ?)Hibernate:     /* update        com.litt.cidp.system.po.Role */ update            role         set            ROLE_NAME=?,            STATUS=?,            REMARK=?         where            ROLE_ID=?Hibernate:     /* delete com.litt.cidp.system.po.Role */ delete         from            role         where            ROLE_ID=?

Hibernate在最终执行SQL语句时,居然是按INSERT, UPDATE, DELETE的顺序执行的,而非按照代码顺序执行!What the F!查阅了相关资料,说是Hibernate为了性能优化,对象操作都是放在缓存里而没有立即执行数据库操作直到commit操作,为的是利用batch操作提高数据库操作性能;老天,那业务逻辑怎么办?同理,在一个事务中混用Hibernate和JDBC操作,将导致数据不一致问题

解决方案:在需要同步的地方(即按照INSERT, UPDATE, DELETE顺序有可能产生问题的时候;混用JDBC操作的时候),执行session.flush()方案,该方法将缓存中的数据请求立即转换为数据库操作并执行。

转载于:https://my.oschina.net/u/699015/blog/145166

你可能感兴趣的文章
bitnami 使用记录
查看>>
Vsftpd+(linux)文件服务器
查看>>
JEPLUS之循环报表—JEPLUS软件快速开发平台
查看>>
从一个线上问题分析binlog与内部XA事务提交过程
查看>>
网页版式设计与平面构图
查看>>
view桌面模板控制usb权限
查看>>
吾日三省吾身
查看>>
【office培训】【王佩丰】Excel2010视频教程第2讲:单元格格式设置
查看>>
android inflate
查看>>
libxml2的编译与安装
查看>>
详述Google针对Android平板App发布的十大开发准则
查看>>
CentOS 7安装python3笔记
查看>>
XenApp 屏幕录像播放提示版本错误
查看>>
linux 通配符、元字符和特殊字符
查看>>
进程控制(学习笔记)
查看>>
hibernate中sorted collection和ordered collection区别
查看>>
“***”眼中云计算的“五大漏洞”
查看>>
网页练习
查看>>
JAVA继承和组合
查看>>
编写一个c语言程序 将一串字符串倒叙存放后输出
查看>>