在过去的几天里,我面临一个相当令人沮丧的问题。我试图通过使用iBatis批量插入来提高性能。但是我发现批量插入失败并出现以下错误之一 - java.sql.BatchUpdateException:IO错误:软件导致连接中止:套接字写入错误 - java.sql.BatchUpdateException:ORA-12161:TNS:内部错误:收到的部分数据 - java.sql.BatchUpdateException:IO错误:软件导致连接中止:recv失败
设置细节如下 - 应用程序服务器是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;
}
});
}
这偶尔会起作用,而在其他时候会出现上述错误之一。 我们正在使用连接池,并且我确保阻塞超时毫秒足够高,尽管我不相信这个值在这里引起了问题。 我已经禁用了防火墙,但仍然看到了同样的问题。 在我看来,连接正在被数据库终止,我通过警报日志(我们正在使用oracle),但没有看到该日志文件上的任何错误。看起来这是一个配置问题,但我不确定需要改变什么,因为我已经尝试了我能想到的一切。 我有什么遗漏的东西吗?
编辑 - 如果我在上面的代码中批量大小为10(batchSize = 10),那么批量插入工作正常。
答案 0 :(得分: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在同一列上为null值/ not null值设置了不同的jdbc类型。根本原因是ibatis映射将一个参数的jdbcType作为数字但对应的java类型为Double。
通过ibatis的ParameterMap步骤#setParameter(PreparedStatement,ParameterMapping,Object [],int),你会发现当值为null时,ibatis将使用jdbcType从你的映射读取setNull。当值不为null时,它将使用typeHandler来设置值。如果没有提供自定义类型处理程序,则typeHandler由TypeHandlerFactory#getTypeHandler(类类型,字符串jdbcType)确定。它由java类型而不是jdbcType驱动。