[英]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,在表中插入我有幾個限制
當我插入生成錯誤時受這些限制
我想運行批處理並省略錯誤 ,此時拋出一個異常結束批處理
在我創建批處理之前,我有一個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:鍵'masterID'的重復條目'1-000002725'
但我需要繼續
spring + hibernate設置是否會干擾jdbc的屬性? 我不知道
我認為可以用一個詞來概括IGNORE
用這個運行批處理時
sb.append("INSERT IGNORE INTO `FRT_DB`.`ITEM` ");
這不會拋出一個Exception ,它會通過約束,傳遞,以及行中的舊數據來實現
如果您需要保存“新數據”, INSERT ... ON DUPLICATE KEY
改為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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.