2015-04-24 8 views
8

Hallo Kerl erstelle ich eine Batch mit einem PreparedStatement in Java wie dieserJDBC PreparedStatement Batch weiterhin auf Fehler einfügen

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 

Der Datebase-Server ist ein MySQL, steckte in Tabelle I mehrere Einschränkungen haben

von diese Einschränkungen, wenn ich erzeugt Fehler einfügen

ich ausführen möchten die Charge und lassen Fehler, in diesem Moment eine Ausnahme ein Wurf endet Batch

Bevor ich den Stapel zu erstellen habe ich eine große für die

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

eins nach dem anderen wie speichern Aber es ist sehr langsam, die Charge procces 4000 Artikel, legen 1500 in einigen Fällen, und lassen Sie den Rest

Wie mache ich mit dem Batch?

EDIT

I WebLogic verwenden conections mit diesem Treiber mysql-connector-java-commercial-5.0.3-bin

Ich teste diese Eigenschaften

1.

continueBatchOnError=true 

2.

rewriteBatchedStatements=true 
012 zu machen

3.

continueBatchOnError=true 
rewriteBatchedStatements=true 

Und connection.setAutoCommit(false); hinzufügen, aber weiter

die Ausnahme in Duplikaten werfen

EDIT

vergaß zu erwähnen, verwende ich für den Anschluss Hibernate + Feder

die einzige For-Save-Beispiel wird in Hibernate gemacht, aber für die Leistung habe ich versucht, einen JDBC-Batch in anderen Prozessen im Web zu verwenden App JDBC auch mit der Verbindung von Hibernate und funktioniert gut

Dies ist der vollständige Code

@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(); 
      } 

     } 
    }); 
} 

Diese produzieren nächste Ausnahme

java.sql.BatchUpdateException: Doppelte Eintrag ‚1-000.002.725 'für Schlüssel 'MasterID'

Aber ich muss weiter

Frühling + Winterschlaf Einstellungen stören die Eigenschaften von jdbc?Ich weiß nicht,

+0

Sind Sie der "MySQL Connector/J" JDBC-Treiber? Wenn dies der Fall ist, sollte das Standardverhalten 'continueBatchOnError = true' sein, was anscheinend das ist, was Sie wollen. –

+0

@GordThompson Ich benutze Weblogic für die Verbindung, ich füge die Eigenschaft 'continueBatchOnError = true' hinzu und starte neu, aber Problem behalte throw exeption in zuerst einfügen' ps.executeBatch(); 'lies später diese [SO post] (http: // stackoverflow .com/questions/26307760/mysql-and-jdbc-with-rewritebatchedstatements-true) und fügen Sie dies 'rewriteBatchedStatements = true' hinzu, aber immer noch die Exception – jasilva

Antwort

6

Ich denke, es kann IGNORE

in einem Wort zusammengefasst werden, wenn Sie die Charge mit diesem

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

Diese KEINE Ausnahme mit Constraints realted werfen laufen, passieren diese über und noch alte Daten in Ihren Zeilen

Wenn Sie die 'neuen Daten' speichern müssen Sie für INSERT ... ON DUPLICATE KEY Statement ändern, aber, jetzt denken Sie nicht brauchen.

Commit oder Rollback ist nicht notwendig in Ihrem Code @Transactional Arbeit für Sie.

Ihr großer try { nur Absturz in SqlException nicht in BatchUpdateException

Sie brauchen nur hinzufügen allowMultiQueries beacuse andere und Standard true

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

+0

Perfekt für mich! – jasilva

Verwandte Themen