【发布时间】:2015-07-03 08:50:23
【问题描述】:
你好,我在 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: 重复条目 '1-000002725' 的键 '主ID'
但我需要继续
spring + hibernate 设置会干扰jdbc的属性吗?我不知道
【问题讨论】:
-
您使用的是“MySQL Connector/J”JDBC 驱动程序吗?如果是这样,默认行为应该是
continueBatchOnError=true,这似乎是你想要的。 -
@GordThompson 我使用 weblogic 进行连接,我添加属性
continueBatchOnError=true并重新启动,但问题仍然存在,在第一次插入时抛出异常ps.executeBatch();稍后阅读此 SO post 并添加此rewriteBatchedStatements=true但是仍然是例外
标签: java mysql spring jdbc weblogic