2011-09-06 115 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驱动。