日期:2014-05-16  浏览次数:20583 次

jdbc+proxool+oracle,当连接池强行关闭链接时,之前的sql操作都被强制提交了
工作中遇到的问题,记录一下

项目中用的连接池版本是proxool-0.9.1
用jdbc来批量操作数据.
连接池的配置maximumActiveTime配的是180000,即(3min)
今天由于网络原因,插入操作11w条数据用了3min多还没好,结果被连接池强行关掉了.
抛出异常,理论上,应该回滚掉所有操作的.可是查看插入记录,入库了10w多条,还有1w多条没进去.
抛出的异常信息
rollback error !
java.sql.SQLException: Couldn't perform the operation rollback: You can't perform any operations on this connection. It has been automatically closed by Proxool for some reason (see logs)

jdbc获取链接代码
try{
conn = SessionFactoryUtils.getDataSource(getSessionFactory()).getConnection();
conn.setAutoCommit(false);
//批量操作
conn.commit();
}catch(Exception e){
try {
conn.rollback();
    } catch (SQLException e1) {
logger.error("rollback error !", e1);
    }
}
spring的事务已关,此方法上加了这个@Transactional(propagation=Propagation.NEVER)

在proxool官网的bug反映里面关于这个问题有人这样写到
Some JDBC implementations - like Oracle - perform an implicit commit before closing a connection, therefore Proxool should always - or at least configurable -rollback the connection before closing it. Otherwise an inconsistent state might be written to the database if the Pool is shutdown via ShutdownHook.
于是我发现悲摧了.08年提交的问题,proxool一直没给予答复和解决办法...
看来这个问题,只能把maximumActiveTime这个参数时间设长,来尽量避免出现这种问题了.
我自己尝试了下在commit之前调用conn.close();数据却没有提交进数据库,估计这么调用的时候,oracle的jdbc有做rollback操作.
而连接池那边在直接杀掉进程之前没做rollback操作...

目前除了把这个参数maximumActiveTime调大之外没想到其他解决办法.