文档章节

oracle jdbc 邪恶数字"65536" ---批量插入10万条记录引发的“血案”

liuxw0226
 liuxw0226
发布于 2016/04/08 17:51
字数 682
阅读 230
收藏 7

1.   故事背景:

mysql数据迁移到oracle,其中有个表名叫“bil_vip”,有10万条记录,迁移后检查发现oracle数据库只插入34464条记录,程序执行过程没有发现任何错误。修改数据库连接代码向mysql插入10万条记录,结果都插入OK。

批量插入使用spring jdbctemplate.batchUpdate(sql, new BatchPreparedStatementSetter());方法,该方法的核心是PreparedStatement的executeBatch方法。

2.   继续实验:

新建一个Test表,只有一个name字段做实验。

抛弃jdbctemplate,直接使用PreparedStatement做实验,结果和jdbcTemplate是一样的,实验证明总是会丢失65536条记录。

oracle 驱动的问题?换了最新driver,还是不行。继续探索....

3.   希望之光:

早上发了个消息向大家征求思路,继中说了一句分批处理,点亮了我的思路。按照继中提供思路,每1万条记录一批,分多批发送给Oracle。

结果喜出望外,10万条记录全部插入成功。但是"65536"这个数字是什么意思呢......     

在网上搜索文章发现,这个65536是一个bug。当PreparedStatement批量处理正好65536个记录时候,程序会挂死。我试了一下真的挂死了,太吓人了,这坑够深的。

4.   解决方案:

spring jdbctemplate还是很好用的,而且业务已经被我封装了,如果使用PreparedStatement意味着多了一个处理分支,以后维护会很麻烦。

我新建一个MyJdbcTemplate类,继承 jdbctemplate类,并覆盖了batchUpdate方法。这下舒服了,系统又恢复了整洁。      

5.   ★ 结论和收获:

ü  有事多思考,多请教身边同事。

ü  坚持Open-close原则(Open for extension, Closed for modification)会系统更好的扩展,非常容易维护,关键是要坚持这个原则,如果我因为一个特殊分支使用了PreparedStatement,这样势必破坏了这个原则,日后的维护必然会很麻烦。

ü  基于oracle数据如果使用jdbc批量,一定要分批发送数据oracle,否则正好发一个65536系统就挂死,大于65536数据就丢失,杯具呀......

6.   题目何以为“血案”:

周二打球回家就想这个问题,打开笔记本调试,不知不觉搞到很晚,影响媳妇睡觉(媳妇早上5:30上班),被痛骂一顿,赶紧上床睡觉,我媳妇气的不行,手痛砸了一下床板(我们的床撤掉了床垫,只有床架和木板),床一下子塌了,把媳妇吓坏了,把我腿弄伤了一块,唉,“血案”呀。

本文转载自:http://www.blogjava.net/alancxx/archive/2013/02/21/369106.html?opt=admin

liuxw0226

liuxw0226

粉丝 9
博文 19
码字总数 8419
作品 0
顺义
后端工程师
私信 提问
加载中

评论(2)

l
lijianlin5200
13
车开源
车开源
我用JDBC从MySQL同步120W数据到Oracle时也遇到过,改为每1000条记录就commit一次,速度钢钢的
JAVA客户端传递对象数组到Oracle存储过程做大数据量插入

最近在项目中用到了JAVA客户端传递对象数组到Oracle存储过程做大数据量插入,比如10万级别. 下面做一个插入10万条记录的示例步骤,,为了容易理解,表的结果很简单. 1,假设表结构如下: 2,在数据库...

晨曦之光
2012/04/25
472
0
Oracle的JDBC驱动的版本你了解吗?

classes12.jar,ojdbc14.jar,ojdbc5.jar和ojdbc6.jar的区别,之间的差异 在使用Oracle JDBC驱动时,有些问题你是不是通过替换不同版本的Oracle JDBC驱动来解决的?最常使用的ojdbc14.jar有多...

i33
2012/02/20
0
0
mysql数据库千万级别数据的查询优化和分页测试

我原来的公司是一家网络游戏公司,其中网站交易与游戏数据库结合通过ws实现的,但是交易记录存放在网站上,级别是千万级别的数据库是mysql数据库. 可能有人会问mysql是否支持千万级数据库,还有既...

idea_biu
2012/07/02
0
0
hibernate批量修改,批量删除

在Hibernate应用中如何处理批量更新和批量删除? 批量更新是指在一个事务中更新大批量数据,批量删除是指在一个事务中删除大批量数据。以下程序直接通过Hibernate API批量更新CUSTOMERS表中年...

Kerry_Han
2013/08/30
0
0
java读取文本,把读取的记录插入mysql,效率问题,10万条数据用了31秒...求更好的方法

格式内容如下: 插入数据库结果: 代码: 10万条记录: java读取文本,把读取的记录插入mysql,效率问题,10万条数据用了31秒...求更好的方法

Smile月光
2013/10/25
5.7K
7

没有更多内容

加载失败,请刷新页面

加载更多

RS-232、RS422和RS-485的区别和各自的实现方式

一、殊途同归 RS-232、RS422和RS-485 均属于UART是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),仅用两根信号线(Rx 和Tx)就可以完成通信过程; 而由于各自使用的电...

rainbowcode
41分钟前
0
0
spring 本类中方法调用另外一个方法事务不生效

1、在spring配置文件中添加 <aop:aspectj-autoproxy expose-proxy="true" proxy-target-class="true" />声明自动代理 <!-- 标识通过aop框架暴露该代理,aopContext能够访问. --> proxy-targe......

重城重楼
47分钟前
5
0
项目 banner 乱弹

------------------------------------------ 村上春树 ------------------------------------- 如果我爱你,而你也正巧爱我,你头发乱了的时候,我会笑笑地替你拨一拨,然后手还留恋地在你...

宿小帅
59分钟前
3
0
PHP获取未来七天的日期和星期

php获取未来七天的日期和星期代码 第一步:获取需要天数的日期,然后调用函数 //获取未来七天的日期 for($i=1;$i<8;$i++){ $dateArray[$i]=date('Y-m-d',strtotime(d...

一只懒猫-
今天
2
0
总结:IO模型

分类 多路复用 参考文章: https://www.jianshu.com/p/6a6845464770 https://www.cnblogs.com/zingp/p/6863170.html https://blog.csdn.net/sehanlingfeng/article/details/78920423......

浮躁的码农
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部