大家好我在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,在表中插入我有几个限制
当我插入生成错误时受这些限制
我想运行批处理并省略错误,此时抛出一个异常结束批处理
在创建批处理之前,我一个接一个地保存Big,如
//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);
但继续在重复项中抛出异常
修改
忘了提,我用于连接Hibernate + Spring
唯一的For-Save示例是在Hibernate中创建的,但是为了性能,我尝试使用JDBC Batch,在webapp的其他过程中也使用JDBC与Hibernate的连接并且运行良好
这是完整的代码
@Transactional
public void saveMany(final List<Item> 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();
}
}
});
}
这会产生下一个例外
java.sql.BatchUpdateException:重复条目&#39; 1-000002725&#39;为了钥匙 &#39; masterID&#39;
但我需要继续
spring + hibernate设置是否会干扰jdbc的属性?我不知道
答案 0 :(得分:7)
我认为可以用一个词IGNORE
使用此
运行批处理时sb.append("INSERT IGNORE INTO `FRT_DB`.`ITEM` ");
这个不会抛出异常与约束,此传递以及行中仍有旧数据相关
如果您需要保存“新数据”,请更改INSERT ... ON DUPLICATE KEY
语句,但是,现在认为不需要它。
代码@Transactional
中的提交或回滚不是必需的。
您的大try {
仅在SqlException中崩溃,而不是在BatchUpdateException
您只需添加allowMultiQueries
beacuse other和default true
http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html