JDBC PreparedStatement Batch continue insert on error
JDBC PreparedStatement Batch continue insert on error
你好,我在 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,在table中插入我有几个限制
由于这些限制,我在插入时产生了错误
我要运行批处理并省略错误,此时抛出异常a结束批处理
在我创建批次之前我有一个大的保存一个一个喜欢
//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 批处理,在 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: Duplicate entry '1-000002725' for key
'masterID'
但我需要继续
spring + 休眠设置会干扰 jdbc 的属性?我不知道
我觉得一个字可以概括IGNORE
当你运行批次
sb.append("INSERT IGNORE INTO `FRT_DB`.`ITEM` ");
这不会抛出异常 与约束相关,这会过去,并且您的行中仍然是旧数据
如果您需要保存 'new data' 则更改为 INSERT ... ON DUPLICATE KEY
语句,但是,现在认为不需要它。
您的代码中不需要提交或回滚 @Transactional
适合您。
你的大 try {
只在 SqlException 中崩溃,而不是在 BatchUpdateException
中崩溃
您只需要添加 allowMultiQueries
因为其他和默认 true
http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html
你好,我在 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,在table中插入我有几个限制
由于这些限制,我在插入时产生了错误
我要运行批处理并省略错误,此时抛出异常a结束批处理
在我创建批次之前我有一个大的保存一个一个喜欢
//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 批处理,在 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: Duplicate entry '1-000002725' for key 'masterID'
但我需要继续
spring + 休眠设置会干扰 jdbc 的属性?我不知道
我觉得一个字可以概括IGNORE
当你运行批次
sb.append("INSERT IGNORE INTO `FRT_DB`.`ITEM` ");
这不会抛出异常 与约束相关,这会过去,并且您的行中仍然是旧数据
如果您需要保存 'new data' 则更改为 INSERT ... ON DUPLICATE KEY
语句,但是,现在认为不需要它。
您的代码中不需要提交或回滚 @Transactional
适合您。
你的大 try {
只在 SqlException 中崩溃,而不是在 BatchUpdateException
您只需要添加 allowMultiQueries
因为其他和默认 true
http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html