2011-04-18 100 views
2

我想使用ojdbc14.jar驅動程序和Spring的SimpleJdbcTemplate batchUpdate方法將超過100,000條記錄插入到沒有主鍵的Oracle 9i表中。這裏是我的代碼片段:甲骨文批插入瓦特/沒有主鍵缺失插入

private static final String TABLE_INSERT = "insert into TABLE_FINAL (ID, START_TIME, VALUE) VALUES (ID_SEQ.NEXTVAL, :startTime, :value)"; 

log.info("inputData list size={}",inputData.size()); 
Object[] dataArray = inputData.toArray(); 
log.info("dataArray length={}",dataArray.length); 

final SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(inputData.toArray()); 
log.info("SqlParamterSource length={}", batch.length); 

final int[] inserted = getJdbcTemplateJoa().batchUpdate(TABLE_INSERT, batch); 

for(int i=0; i < inserted.length; i++){ 
if(inserted[i] != -2){ 
    System.out.println("i="+i +" insert[i]="+inserted[i]); 
    System.out.println(batch[i]); 
} 

}

的inputData名單,dataArray中的大小,和一批長度都是相同的預期值。 batchUpdate完成時不會拋出任何異常,隨後的for循環不會打印任何內容,因爲插入數組中的每個項都返回-2(成功)。但是,只有42,000條記錄被保留到目標表,而不是預期的100,000條以上的記錄。

如果我用輸入集合上的循環來替換batchUpdate併爲每個項目執行更新,則會保留100,000+條記錄。但是,我想使用batchUpdate來利用改進的性能。

有沒有人有任何想法,爲什麼batchUpdate不起作用?我不禁想到它與缺少的主鍵有關。

下面是這是我們用來填充inputData列表源表中的數據:

0.1933,-0.0253,0,0,4/16/2011 5:00:00 AM,4/16/2011 6:00:00 AM,12,9,1,1 
0.1917,-0.0253,0,0,4/16/2011 6:00:00 AM,4/16/2011 7:00:00 AM,12,9,1,1 
0.1936,-0.0253,0,0,4/16/2011 7:00:00 AM,4/16/2011 8:00:00 AM,12,9,1,1 
0.2017,-0.0253,0,0,4/16/2011 8:00:00 AM,4/16/2011 9:00:00 AM,12,9,1,1 
0.2083,-0.0253,0,0,4/16/2011 9:00:00 AM,4/16/2011 10:00:00 AM,12,9,1,1 
0.2133,-0.0253,0,0,4/16/2011 10:00:00 AM,4/16/2011 11:00:00 AM,12,9,1,1 
0.2238,-0.0253,0,0,4/16/2011 11:00:00 AM,4/16/2011 12:00:00 PM,12,9,1,1 
0.2309,-0.0253,0,0,4/16/2011 12:00:00 PM,4/16/2011 1:00:00 PM,12,9,1,1 
0.2319,-0.0253,0,0,4/16/2011 1:00:00 PM,4/16/2011 2:00:00 PM,12,9,1,1 
0.231,-0.0253,0,0,4/16/2011 2:00:00 PM,4/16/2011 3:00:00 PM,12,9,1,1 
0.2283,-0.0253,0,0,4/16/2011 3:00:00 PM,4/16/2011 4:00:00 PM,12,9,1,1 
0.2216,-0.0253,0,0,4/16/2011 4:00:00 PM,4/16/2011 5:00:00 PM,12,9,1,1 
0.2164,-0.0253,0,0,4/16/2011 5:00:00 PM,4/16/2011 6:00:00 PM,12,9,1,1 
0.2155,-0.0253,0,0,4/16/2011 6:00:00 PM,4/16/2011 7:00:00 PM,12,9,1,1 
0.2162,-0.0253,0,0,4/16/2011 7:00:00 PM,4/16/2011 8:00:00 PM,12,9,1,1 
0.2187,-0.0253,0,0,4/16/2011 8:00:00 PM,4/16/2011 9:00:00 PM,12,9,1,1 
0.2203,-0.0253,0,0,4/16/2011 9:00:00 PM,4/16/2011 10:00:00 PM,12,9,1,1 
0.2296,-0.0253,0,0,4/16/2011 10:00:00 PM,4/16/2011 11:00:00 PM,12,9,1,1 
0.2323,-0.0253,0,0,4/16/2011 11:00:00 PM,4/17/2011,12,9,1,1 
0.2293,-0.0253,0,0,4/17/2011,4/17/2011 1:00:00 AM,12,9,1,1 
0.2154,-0.0253,0,0,4/17/2011 1:00:00 AM,4/17/2011 2:00:00 AM,12,9,1,1 
0.2088,-0.0253,0,0,4/17/2011 2:00:00 AM,4/17/2011 3:00:00 AM,12,9,1,1 
0.202,-0.0253,0,0,4/17/2011 3:00:00 AM,4/17/2011 4:00:00 AM,12,9,1,1 
0.1916,-0.0253,0,0,4/17/2011 4:00:00 AM,4/17/2011 5:00:00 AM,12,9,1,1 

和這裏的BATCHUPDATE後所得到持續:

47987296,4/19/2011 4:37:15 PM,0.1933,-0.0253,4/16/2011 5:00:00 AM,4/16/2011 6:00:00 AM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47961249,4/19/2011 4:37:15 PM,0.2238,-0.0253,4/16/2011 11:00:00 AM,4/16/2011 12:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47966094,4/19/2011 4:37:15 PM,0.2309,-0.0253,4/16/2011 12:00:00 PM,4/16/2011 1:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47968596,4/19/2011 4:37:15 PM,0.2319,-0.0253,4/16/2011 1:00:00 PM,4/16/2011 2:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47972962,4/19/2011 4:37:15 PM,0.231,-0.0253,4/16/2011 2:00:00 PM,4/16/2011 3:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47978129,4/19/2011 4:37:15 PM,0.2283,-0.0253,4/16/2011 3:00:00 PM,4/16/2011 4:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47982943,4/19/2011 4:37:15 PM,0.2216,-0.0253,4/16/2011 4:00:00 PM,4/16/2011 5:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
48005719,4/19/2011 4:37:15 PM,0.2164,-0.0253,4/16/2011 5:00:00 PM,4/16/2011 6:00:00 PM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47990490,4/19/2011 4:37:15 PM,0.2088,-0.0253,4/17/2011 2:00:00 AM,4/17/2011 3:00:00 AM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
47993531,4/19/2011 4:37:15 PM,0.202,-0.0253,4/17/2011 3:00:00 AM,4/17/2011 4:00:00 AM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 
48000722,4/19/2011 4:37:15 PM,0.1916,-0.0253,4/17/2011 4:00:00 AM,4/17/2011 5:00:00 AM,4/19/2011 4:37:28 PM,9,12,1,1,04-15-2011 

源表中的24行也應目標表中有24行,但只有11行被填充。

+0

我修改了表以使用ID作爲主鍵,然後用batchUpdate重試了持久性。不幸的是,batchUpdate仍然只保存了47,000條記錄而不是100,000條記錄。 – jlentz 2011-04-18 20:22:21

+0

序列的值會發生什麼?這是否反映了100000或47000?你什麼時候做提交? – 2011-04-19 05:44:33

+0

該序列反映了47000個計數。 batchUpdate是消息驅動bean的onMessage方法中的最後一個方法調用,因此在batchUpdate成功返回後發生提交。 – jlentz 2011-04-19 14:22:32

回答

1

當使用SimpleJdbcTemplate.batchUpdate(String sql,SqlParameterSource []源)與ojdbc14.jar和大量的數據(超過60K)時,正如我在原始發佈中所述,目標表中缺少數據。我發現,如果我將輸入數據分成10K塊,那麼數據會成功保存。我也試過使用JdbcTemplate.batchUpdate(String [] sql)方法,它保持正確,但比循環和調用SimpleJdbcTemplate.update慢。另一方面,JdbcTemplate.batchUpdate(String [] sql)返回一個int [],其中數組中的每個項目都包含受影響的行數。

我將Oracle驅動程序更改爲ojdbc6.jar,並使用SimpleJdbcTemplate.batchUpdate(String sql,SqlParamterSource [] source)在所有100,000個源記錄中傳遞並重新測試!不幸的是,我們有其他需要ojdbc14.jar的依賴項,所以我們不能升級。

對於最終的解決方案,數據將被分解爲如下所示的10K塊,並且在batchUpdate之後將添加驗證數據的sql查詢。

if(inputData.size() > 10000){ 

      int beginIndex =0; 
      int endIndex = 10000; 
      List<InputData> partialList = null; 
      while(beginIndex < inputData.size()){ 
       partialList = inputData.subList(beginIndex, endIndex); 

       final SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(partialList.toArray()); 

       getJdbcTemplateJoa().batchUpdate(TABLE_INSERT, batch); 

       beginIndex = endIndex; 
       endIndex = endIndex + 10000 < inputData.size() ? endIndex + 10000 : inputData.size(); 
      } 
} else{ 

      final SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(inputData.toArray()); 
      getJdbcTemplateJoa().batchUpdate(TABLE_INSERT, batch); 

     } 
0

也許有一些例外被捕獲並且沒有通過。嘗試安裝一個servererror觸發器來確定Oracle是否向客戶端傳遞了任何異常。

Here你會發現一個例子。

順便說一句,我會對你一旦工作後取得的性能改進感興趣。我不會感到驚訝,如果它沒有區別...

+0

我們的DBA爲我們設置了觸發器,並記錄在error_log表中,如您所提供的鏈接所述。不幸的是,表中只記錄了SQL錯誤(例如,表/視圖不存在)。不過謝謝你的建議。 – jlentz 2011-05-05 15:20:21