2011-09-06 135 views
0

我在過去幾天面臨一個相當令人沮喪的問題。我試圖通過使用iBatis批量插入來提高性能。但是,我看到批量插入失敗,出現以下錯誤之一 - java.sql.BatchUpdateException:IO錯誤:軟件導致連接中止:套接字寫入錯誤 - java.sql.BatchUpdateException:ORA-12161:TNS:內部錯誤:部分數據接收 - java.sql.BatchUpdateException:IO錯誤:軟件導致連接中止:recv的失敗iBatis批量插入失敗,出現套接字寫入錯誤

設置的細節是如下 - 應用服務器是Jboss的5.0.1 - iBatis的2.3.4.732.1 - 彈簧2.5.6

我擁有的批量插入代碼如下

try 
    { 
     final String finalStatement = statementName; 
     int size = parameterList.size(); 
     int batchSize = 100; 

     for(int ii=0; ii < size;) 
     { 
      int toIndex = ((ii + batchSize) > size ? size : (ii+batchSize)); 

      final List<Object> subList = parameterList.subList(ii, toIndex); 
      ii += batchSize; 
      count = getSqlMapClientTemplate().execute(new SqlMapClientCallback() 
      { 
       public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException 
       { 
        executor.startBatch(); 
        for(Object finalParameterObject : subList) 
        {     
         executor.insert(finalStatement, finalParameterObject); 
        } 
        Integer retCount = new Integer(executor.executeBatch()); 
        return retCount; 
       } 
      });      
     } 

偶爾出現這種情況,並且在其他時間失敗並出現上述錯誤之一。 我們正在使用一個連接池,並且確保blocking-timeout-millis足夠高,但我不相信這個值在這裏引起問題。 我已禁用防火牆,但仍然看到相同的問題。 在我看來,連接正在被數據庫終止,我通過警報日誌(我們正在使用oracle),但沒有看到該日誌文件上的任何錯誤。看起來這是一個配置問題,但我不確定需要改變什麼,因爲我嘗試了所有我能想到的事情。 有什麼我缺少的東西?

編輯 - 如果我在上面的代碼中批量大小爲10(batchSize = 10),那麼批量插入工作正常。

回答

0

我無法評論,答案是基於一些假設:

你使用iBATIS 2.3或3.x版?如果它是2.3,你是否將jdbcType設置爲NUMERIC,但是支持java的字段是Double/double?或者在ibatis映射中實際的java類型和jdbc類型之間有類似的不匹配?

我有一個類似的批處理套接字死鎖問題與ibatis 2.3,spring-orm和postgresql。打開Postgresql JDBC驅動程序的調試日誌記錄後,找到許多解析消息,這些消息是假設爲一個的。事實證明,ibatis在同一列上爲空值/非空值設置了不同的jdbc類型。根本原因是ibatis映射有一個參數的jdbcType作爲數字,但相應的java類型是Double。你會發現什麼時候這個值爲null,ibatis會從你的映射中讀取jdbcType的setNull。當該值不爲空時,它將使用typeHandler來設置值。如果沒有提供自定義類型處理程序,則typeHandler由TypeHandlerFactory#getTypeHandler(Class type,String jdbcType)確定。它由java類型而不是jdbcType驅動。