alancxx

------简单就是美

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

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上班),被痛骂一顿,赶紧上床睡觉,我媳妇气的不行,手痛砸了一下床板(我们的床撤掉了床垫,只有床架和木板),床一下子塌了,把媳妇吓坏了,把我腿弄伤了一块,唉,“血案”呀。

posted on 2012-01-31 20:17 蜂鸟 阅读(1433) 评论(1)  编辑  收藏 所属分类: j2ee架构

评论

# re: oracle jdbc 邪恶数字"65536" ---批量插入10万条记录引发的“血案” 2013-02-21 13:02 日出星辰

文笔很不错!
能把覆盖batchUpdate方法那段代码展示一下吗?我被这个问题折磨了好长时间了  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问  
 

公告

 掌握了XML就掌握了未来!

导航

<2013年2月>
272829303112
3456789
10111213141516
17181920212223
242526272812
3456789

统计

常用链接

留言簿

随笔档案(1)

文章分类(17)

文章档案(17)

搜索

最新评论