2015-04-24 3 views
8

Привет парня Я создаю Batch с PreparedStatement в Java, как этогоJDBC PreparedStatement Batch продолжает вставлять на ошибках

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 

The datebase сервер является MySQL, в таблице для вставки У меня есть несколько ограничений

По эти ограничения при вставке порождает ошибку

Я хочу, чтобы запустить пакет и опустить ошибку позиционирования, в этот момент бросить исключение и заканчивается партия

Перед тем, как создать партию у меня есть большой для сохранения один за другим, как

//seudocode level 
For item 
Try{ 
    insert item 
}catch(E){nothing happens} 

Но это очень медленно, в некоторых случаях, партии procces 4000 пункт, вставить 1500 и опустить

остальное

Как мне сделать с партией?

EDIT

Я использую WebLogic, чтобы conections с этим драйвером mysql-connector-java-commercial-5.0.3-bin

Я проверить это свойства

1.

continueBatchOnError=true 

2.

rewriteBatchedStatements=true 

3.

continueBatchOnError=true 
rewriteBatchedStatements=true 

И добавить connection.setAutoCommit(false);, но продолжает бросать исключение в копиях

EDIT

забыл упомянуть, я использую для подключения гибернации + Spring

только Например, для сохранения в Hibernate, но для производительности я попытался использовать пакет JDBC, в других продуктах в Интернете Приложение также использовать 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 'для ключа 'masterID'

Но мне нужно продолжать

Настройки пружины + спящий режим влияют на свойства jdbc?Я не знаю

+0

Вы используете драйвер JDBC "MySQL Connector/J"? Если это так, поведение по умолчанию должно быть 'continueBatchOnError = true', которое, похоже, вам нужно. –

+0

@GordThompson Я использую weblogic для подключения, я добавляю свойство 'continueBatchOnError = true' и перезапускаю, но проблема остается в том, чтобы удалить exeption в первой вставке' ps.executeBatch(); 'позже прочитайте это [SO post] (http: // stackoverflow .com/questions/26307760/mysql-and-jdbc-with-rewritebatchedstatements-true) и добавьте это 'rewriteBatchedStatements = true', но все равно исключение – jasilva

ответ

6

Я думаю, что это можно выразить одним словом IGNORE

При запуске партии с этим

sb.append("INSERT IGNORE INTO `FRT_DB`.`ITEM` "); 

Это НЕ бросить исключение realted с ограничениями, это пройти через , и все еще старые данные в ваших строках

Если вам нужно сохранить новые данные, то вы измените их на INSERT ... ON DUPLICATE KEY Заявление, но сейчас его не нужно.

Обязательно или отката в вашем коде не обязательно @Transactional.

Ваш большой try { только авария в SqlException не BatchUpdateException

Вам нужно только добавить allowMultiQueries beacuse другой и по умолчанию true

http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html

+0

Идеально для меня! – jasilva

Смежные вопросы