2011-04-18 70 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