Java 取消通过 JDBC 运行 Oracle 查询的任务 - 连接因 SQLSTATE(08006)、ErrorCode(17002) IO 错误而中断:套接字读取中断

问题描述 投票:0回答:1

Java自定义ThreadPool - 暂停任务提交并取消当前排队的任务开始,我正在实现一种机制来关闭特定连接上正在进行的查询一段时间。底层 JDBC 连接池由 HikariCP 保证。通过调用 preparedstatement close 来取消正在进行的查询,如此处数据库查询中断所述。 即使这样做我也收到以下错误:

Connection oracle.jdbc.driver.T4CConnection@4bc28c33 marked as broken because of SQLSTATE(08006), ErrorCode(17002)

marked as broken because of SQLSTATE(08006), ErrorCode(17002)

java.sql.SQLRecoverableException: IO Error: Socket read interrupted
    at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:821)
    at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:983)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1168)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3666)
    at oracle.jdbc.driver.T4CPreparedStatement.executeInternal(T4CPreparedStatement.java:1426)
    at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3713)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1167)
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.io.InterruptedIOException: Socket read interrupted
    at oracle.net.nt.TimeoutSocketChannel.handleInterrupt(TimeoutSocketChannel.java:258)
    at oracle.net.nt.TimeoutSocketChannel.read(TimeoutSocketChannel.java:180)
    at oracle.net.ns.NSProtocolNIO.doSocketRead(NSProtocolNIO.java:555)
    at oracle.net.ns.NIOPacket.readHeader(NIOPacket.java:258)
    at oracle.net.ns.NIOPacket.readPacketFromSocketChannel(NIOPacket.java:190)
    at oracle.net.ns.NIOPacket.readFromSocketChannel(NIOPacket.java:132)
    at oracle.net.ns.NIOPacket.readFromSocketChannel(NIOPacket.java:105)
    at oracle.net.ns.NIONSDataChannel.readDataFromSocketChannel(NIONSDataChannel.java:91)
    at oracle.jdbc.driver.T4CMAREngineNIO.prepareForUnmarshall(T4CMAREngineNIO.java:764)
    at oracle.jdbc.driver.T4CMAREngineNIO.unmarshalUB1(T4CMAREngineNIO.java:429)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:407)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:268)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:655)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:270)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:91)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:807)
    ... 16 common frames omitted
java jdbc
1个回答
0
投票

由于我在这个问题上浪费了一天的时间,我将向其他人发布解决方案:使用运行应用程序

-Doracle.jdbc.javaNetNio=false

解决问题。

这里

12.2.0.1 及更高版本的 JDBC 驱动程序在阻塞模式下使用 Java NIO 调用,这可能会受到应用程序发出的任何 Interrupt() 调用的影响。 这与以前版本的 JDBC 驱动程序不同,后者使用基于流的 I/O API 调用,不受 Interrupt() 调用的影响。 这是从 12.2.0.1 JDBC 驱动程序开始的有意/有意的更改。

检查应用程序代码中是否有任何 Interrupt() 方法调用。

或者,在应用程序 tra 文件中设置以下连接属性:oracle.jdbc.javaNetNio=false 例子: -Doracle.jdbc.javaNetNio=false

这将指示 JDBC 驱动程序恢复到使用基于流的 I/O API 调用的 12.2 之前的行为,不受 Interrupt() 方法调用的影响。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.