2016-05-07 19 views
10

Mentre jdbcTemplate.batchUpdate (...) è in esecuzione, posso vedere che il conteggio delle righe db viene aumentato gradualmente (eseguendo il conteggio (*) nella tabella), inizialmente 2k e poi 3k fino a 10k. 2k e 3k non sono numeri esatti a volte ottengo 2357 quindi 4567.Spring jdbcTemaplate come inviare la dimensione batch completa al server DB2 in un solo colpo?

Mi aspettavo 10 k righe (dimensione del lotto) da impegnare in un colpo. A mio avviso, se inizialmente ottengo il conteggio delle righe 0, il conteggio delle righe successive dovrebbe essere 10k. Non voglio uno per uno inserto per motivi di prestazioni, ecco perché la funzione di batchupdate utilizzata e sembra che non impegna tutto in uno scatto.

Desidero inviare dati (righe 10k) al server DB una sola volta per il mio lotto. perché c'è qualcosa che dovrei specificare nella configurazione?

Di seguito è riportato il modo in cui sto scrivendo l'aggiornamento batch di jdbcTemplate. il lotto di grandezza è 10k.

public void insertRows(...) { 
    ... 
    jdbcTemplate.batchUpdate(query, new BatchPreparedStatementSetter(){ 
    @Override public void 

    setValues(PreparedStatement ps, int i) throws SQLException { 
     ... 
    } 

    @Override public int getBatchSize() { 
     if(data == null){ 
      return 0; 
     } 
     return data.size(); 
    } 
    }); 
} 

Modifica: Aggiunto @Transactional al metodo isertRows stiil posso vedere lo stesso comportamento. usando Transnazionale si impegna dopo 10k righe, ma quando vedo contare usando con UR (seleziona count (*) da mytable con ur) mostra i dati che vengono aggiornati gradualmente (2k 4k così via fino a 10k). Ciò significa che i dati vengono inviati al server in blocchi (probabilmente uno ciao uno). Come posso inviare tutto in un colpo solo. This question suggerisce di essere ottenuto usando rewriteBatchedStatements in mysql, c'è qualcosa di simile che abbiamo in DB2.

Sto usando implementazione DataSource com.ibm.db2.jcc.DB2BaseDataSource

+0

@tamasrev La domanda che hai fornito dice che non commette, sto dicendo che impegna prima ancora mi aspetto – Vipin

+0

Oops, giudicati superficialmente. Siamo spiacenti, rimosso la bandiera. –

+0

Se devo applicare le transazioni, allora cosa sta facendo l'aggiornamento batch? Posso farlo anche in un singolo aggiornamento. – Vipin

risposta

0

Come sul metodo seguito? specificare nUpdates = 10.000 nel tuo caso. Non ho provato a test this.please ignorare la mia risposta se non funziona.

// the batch size is set in the BatchPreparedStatementSetter, the number of rows we want to process is equal to the nbUpdates parameter 
    public int[] batchUpdate(String sql, final long nbUpdates, final BatchPreparedStatementSetter pss) throws DataAccessException { 
     if (logger.isDebugEnabled()) { 
      logger.debug("Executing SQL batch update [" + sql + "]"); 
     } 

     return (int[]) execute(sql, new PreparedStatementCallback() { 
      public Object doInPreparedStatement(PreparedStatement ps) throws SQLException { 
       try { 
        int batchSize = pss.getBatchSize(); 
        InterruptibleBatchPreparedStatementSetter ipss = (pss instanceof InterruptibleBatchPreparedStatementSetter ? (InterruptibleBatchPreparedStatementSetter) pss 
          : null); 
        if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) { 
         List<Integer> rowsAffected = new ArrayList<Integer>(); 
         for (int i = 1; i <= nbUpdates; i++) { 
          pss.setValues(ps, i - 1); 
          if (ipss != null && ipss.isBatchExhausted(i - 1)) { 
           if (logger.isDebugEnabled()) { 
            int batchIdx = (i % batchSize == 0) ? i/batchSize : (i/batchSize) + 1; 
            logger.debug("Batch exhausted - Sending last SQL batch update #" + batchIdx); 
           } 
           int[] res = ps.executeBatch(); 
           for (int j = 0; j < res.length; j++) { 
            rowsAffected.add(res[j]); 
           } 
           break; 
          } 
          ps.addBatch(); 
          if (i % batchSize == 0 || i == nbUpdates) { 
           if (logger.isDebugEnabled()) { 
            int batchIdx = (i % batchSize == 0) ? i/batchSize : (i/batchSize) + 1; 
            logger.debug("Sending SQL batch update #" + batchIdx); 
           } 
           int[] res = ps.executeBatch(); 
           for (int j = 0; j < res.length; j++) { 
            rowsAffected.add(res[j]); 
           } 
          } 
         } 
         int[] result = new int[rowsAffected.size()]; 
         for (int i = 0; i < result.length; i++) { 
          result[i] = rowsAffected.get(i).intValue(); 
         } 
         return result; 
        } else { 
         List<Integer> rowsAffected = new ArrayList<Integer>(); 
         for (int i = 0; i < nbUpdates; i++) { 
          pss.setValues(ps, i); 
          if (ipss != null && ipss.isBatchExhausted(i)) { 
           break; 
          } 
          rowsAffected.add(ps.executeUpdate()); 
         } 
         int[] rowsAffectedArray = new int[rowsAffected.size()]; 
         for (int i = 0; i < rowsAffectedArray.length; i++) { 
          rowsAffectedArray[i] = rowsAffected.get(i); 
         } 
         return rowsAffectedArray; 
        } 
       } finally { 
        if (pss instanceof ParameterDisposer) { 
         ((ParameterDisposer) pss).cleanupParameters(); 
        } 
       } 
      } 
     }); 
    } 
+0

jdbcTemplate.batchupdate utilizza codice simile a quello che hai fornito. Penso che non possa migliorare le prestazioni. – Vipin

Problemi correlati