oracle - 将 Oracle 驱动程序更新到 12.2.0.1.0 后出现“java.sql.SQLRecoverableException:IO 错误:操作中断”
问题描述
我最近将我们的 Oracle JDB 驱动程序更新为 12.2.0.1.0。
更新后,我们只是从 Oracle 驱动程序中得到了一些我们还没有遇到过的错误,我还没有找到关于如何解决这个问题的讨论。
我们在公司开发的应用程序有一个调度程序,用于管理不同作业的执行。
这些作业可以打开与数据库的连接并对其执行一些 SQL 查询(然后当然会关闭连接)。
这些作业是并行执行的(使用分叉机制)。
当然,最多可以并行执行的作业。
如果当前没有执行作业,则等待执行。
可以使用队列管理可以执行的作业的顺序。
以下错误发生在以下情况:调度程序并行执行允许同时运行的最大作业数,并且有作业等待执行。
在将要启动等待作业的那一刻(这意味着正在运行的作业已完成并且可以启动新作业)发生以下错误:
Caused by: de.fact.first.process.data.ProcessDataException:
java.sql.SQLRecoverableException: IO Error: Operation interrupted
at
JobDataFactoryImplJDBC.getByJobId(JobDataFactoryImplJDBC.java:210)
... 19 more
Caused by: java.sql.SQLRecoverableException: IO Error: Operation interrupted
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:761)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:904)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1082)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3780)
at oracle.jdbc.driver.T4CPreparedStatement.executeInternal(T4CPreparedStatement.java:1343)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3822)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1165)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83)
at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83)
at de.fact.first.process.data.JobDataFactoryImplJDBC.getByJobId(JobDataFactoryImplJDBC.java:205)
... 19 more
Caused by: java.io.InterruptedIOException: Operation interrupted
at oracle.net.nt.TimeoutSocketChannel.handleInterrupt(TimeoutSocketChannel.java:311)
at oracle.net.nt.TimeoutSocketChannel.write(TimeoutSocketChannel.java:221)
at oracle.net.ns.NIOPacket.writeToSocketChannel(NIOPacket.java:211)
at oracle.net.ns.NIONSDataChannel.writeDataToSocketChannel(NIONSDataChannel.java:181)
at oracle.net.ns.NIONSDataChannel.writeDataToSocketChannel(NIONSDataChannel.java:132)
at oracle.jdbc.driver.T4CMAREngineNIO.prepareForReading(T4CMAREngineNIO.java:96)
at oracle.jdbc.driver.T4CMAREngineNIO.unmarshalUB1(T4CMAREngineNIO.java:534)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:485)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:252)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:612)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:226)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:59)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:747)
... 28 more
我的第一个想法是,可能应用程序超过了连接数,因此 Oracle 中断了连接。
这不是问题,因为我增加了进程(和会话)的数量以及另外的分布式锁定超时。
即使调整了这些选项,问题仍然存在。
等待作业没有保持打开的连接。
当然,我可以说该错误仅发生在新的 Oracle 驱动程序中,该问题在旧驱动程序 (12.1.0.1.0) 中无法重现。
解决方案
我们通过将OJDBC 驱动程序的配置选项testOnBorrow设置为 true 来解决此问题。同样,如果您使用 Tomcat 作为服务器,您还需要为 Tomcat 配置设置相同的属性为 true:
<Context reloadable="true" >
<Resource name="jdbc/..."
auth="Container"
type="org.apache.commons.dbcp2.PoolingDataSource"
factory=""
scope="Shareable"
dataSource="oracle"
minIdle="0"
maxIdle="50"
maxActive="500"
minEvictableIdleTimeMillis="1800000"
numTestsPerEvictionRun="3"
validationQuery="SELECT COUNT(*) FROM LANGUAGES"
testOnBorrow="true"
testOnReturn="false"
testWhileIdle="true"
timeBetweenEvictionRunsMillis="300000"/>
推荐阅读
- python - Python:使用连接写入文本文件
- anylogic - 如何将逗号添加到 Anylogic 演示文本对象中的数字字符串?
- bash - Bash - if...then 语句 - 意外标记
- sumo - 在 SUMO netedit 中从 3D 模型文件或 CAD 文件生成道路网络
- rest - '具有与报告内容不同的内容' - 尝试使用 RestAssured 上传 JPEG 文件(图像文件)时出现此错误
- android - 在 Android Studio 中通过蓝牙发送 .txt
- ansible - 在不需要的服务器中运行的 Ansible 剧本
- android - 在片段中调用方法
- php - 无法使用 php 7.3 在 ubuntu 19.10 上安装 php-intl 扩展
- automation - 自动创建 Power Bi 报告>