JDBC PreparedStatement批量继续插入错误
大家好我在java中创建一个带有PreparedStatement
的批处理
for(Item item: list){ ps.setString(1, item.getSome()); ps.setString(2, item.getFoo()); ps.setString(3, item.getBatman()); statement.addBatch(); if (++count % batchSize == 0) { results = ps.executeBatch(); //execute parcial batch if (results != null) System.out.println(results.length); } } results= ps.executeBatch(); //execute rest of batch
数据库服务器是一个MySQL,在表中插入我有几个限制
当我插入时通过这些限制生成错误
我想运行批处理并省略错误 ,此时抛出一个exception结束批处理
在我创建批处理之前,我有一个大的保存逐个像
//seudocode level For item Try{ insert item }catch(E){nothing happens}
但它很慢,在某些情况下,批处理产生4000项,插入1500并省略其余部分
我该如何处理批次?
编辑
我使用weblogic与这个驱动程序mysql-connector-java-commercial-5.0.3-bin
我测试了这个属性
1。
continueBatchOnError=true
2。
rewriteBatchedStatements=true
3。
continueBatchOnError=true rewriteBatchedStatements=true
并添加connection.setAutoCommit(false);
但继续抛出重复的exception
编辑
忘了提,我用来连接Hibernate + Spring
唯一的For-Save示例是在Hibernate中创建的,但是为了性能,我尝试使用JDBC Batch,在webapp中的其他过程中也使用JDBC与Hibernate的连接并且运行良好
这是完整的代码
@Transactional public void saveMany(final List items) { getMySqlSession().doWork(new Work() { @Override public void execute(Connection connection) throws SQLException { StringBuilder sb = new StringBuilder(); sb.append("INSERT INTO `FRT_DB`.`ITEM` "); sb.append("( "); sb.append("`masterID`, "); sb.append("`agent`, "); sb.append("`rangeID`) "); sb.append("VALUES "); sb.append("( "); sb.append("?, "); sb.append("?, "); sb.append("?) "); int[] results = null; PreparedStatement ps = null; try { connection.setAutoCommit(false); ps = connection.prepareStatement(sb.toString()); final int batchSize = 250; int count = 0; for (Item item : items) { if (item.getMasterId() != null) { ps.setInt(1, item.getMasterId()); } else ps.setNull(1, java.sql.Types.INTEGER); if (item.getAgent() != null) { ps.setString(2, item.getAgent()); } else ps.setNull(2, Types.VARCHAR); if (item.getRangeId() != null) ps.setInt(3, item.getRangeId()); else ps.setNull(3, Types.INTEGER); ps.addBatch(); if (++count % batchSize == 0) { results = ps.executeBatch(); if (results != null) System.out.println(results.length); } } results= ps.executeBatch(); } catch (Exception e) { e.printStackTrace(); } } }); }
这会产生下一个exception
java.sql.BatchUpdateException:关键字’masterID’的重复条目’1-000002725′
但我需要继续
spring + hibernate设置是否会干扰jdbc的属性? 我不知道
我认为可以用一个词来概括IGNORE
用这个运行批处理时
sb.append("INSERT IGNORE INTO `FRT_DB`.`ITEM` ");
这不会抛出一个Exception ,它带有约束,这个传递,以及行中的旧数据
如果您需要保存“新数据”,则需要更改INSERT ... ON DUPLICATE KEY
Statement,但是,现在认为不需要它。
您的代码@Transactional
工作中不需要提交或回滚。
您的重大try {
仅在SqlException中崩溃而不是在BatchUpdateException中
您只需要添加allowMultiQueries
beacuse other和default true
http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html