簡體   English   中英

JDBC PreparedStatement批量繼續插入錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM