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

1.   故事背景: mysql

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

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

2.   继续实验: 数据库

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

抛弃jdbctemplate,直接使用PreparedStatement作实验,结果和jdbcTemplate是同样的,实验证实老是会丢失65536条记录。 spa

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

3.   但愿之光: 继承

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

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

在网上搜索文章发现,这个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上班),被痛骂一顿,赶忙上床睡觉,我媳妇气的不行,手痛砸了一下床板(咱们的床撤掉了床垫,只有床架和木板),床一会儿塌了,把媳妇吓坏了,把我腿弄伤了一块,唉,“血案”呀。

相关文章
相关标签/搜索