java.sql.SQLRecoverableException:从 Oracle 数据库接收 blob 字段期间关闭连接
java.sql.SQLRecoverableException: Closed Connection during receiving blob field from oracle database
我在从 Oracle 数据库接收 blob 字段时遇到了一个奇怪的问题:“SQLRecoverableException: Closed Connection
描述此异常的堆栈跟踪:
java.sql.SQLRecoverableException: Closed Connection
at oracle.jdbc.driver.OracleBlob.getDBAccess(OracleBlob.java:960) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.OracleBlob.getBinaryStream(OracleBlob.java:319) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.OracleBlob.getBinaryStream(OracleBlob.java:300) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.sql.BLOB.getBinaryStream(BLOB.java:316) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_221]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_221]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_221]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_221]
at org.hibernate.engine.jdbc.SerializableBlobProxy.invoke(SerializableBlobProxy.java:60) ~[hibernate-core-5.3.18.Final.jar:5.3.18.Final]
at com.sun.proxy.$Proxy142.getBinaryStream(Unknown Source) ~[?:?]
at com.xxx.yyy.util.KeystoreHelper.loadKeyStore(KeystoreHelper.java:89) [cphcore-3.23.0.23-SNAPSHOT.jar:?]
at com.xxx.yyy.bp.job.substep.ProcessIF2Files.getChannelUnsealer(IFB2UnsealFiles.java:207) [classes/:?]
at com.xxx.yyy.bp.job.substep.ProcessIF2Files.access(IFB2UnsealFiles.java:198) [classes/:?]
at com.xxx.yyy.bp.job.substep.ProcessIF2Files.execute(IFB2UnsealFiles.java:86) [classes/:?]
at com.xxx.yyy.bp.job.substep.ProcessIF2Files.execute(IFB2UnsealFiles.java:1) [classes/:?]
源代码:classKeystoreHelper方法loadKeyStore:
(...)
Blob keystoreBlob = keystore.getKeystoreData();
if (keystoreBlob == null || keystoreBlob.length() == 0) {
log.error("Keystore data is empty");
throw new KeystoreAccessException(keystore, "Keystore data is empty", null);
}
inputStream = keystore.getKeystoreData().getBinaryStream(); // line 89 - Exception
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
IOUtils.copy(inputStream, outputStream);
inputStream.close();
outputStream.close();
byte[] keystoreData = outputStream.toByteArray();
inputStream = new ByteArrayInputStream(keystoreData);
(...)
变量的源代码 - 密钥库,class DbKeystore(实体),方法 getKeystoreData:
(...)
private java.sql.Blob keystoreData;
public java.sql.Blob getKeystoreData() {
return this.keystoreData;
}
public void setKeystoreData(java.sql.Blob keystoreData) {
this.keystoreData = keystoreData;
}
(...)
大家遇到过类似的问题吗?
感谢您的帮助:)
这很可能是由于底层 JDBC 连接被放回连接池造成的。确保用于加载实体的 EntityManager
或 Session
在您访问 blob 时仍然处于活动状态。
我正在与@lmetrak 一起工作,最后我弄清楚出了什么问题。
我们的应用程序支持 Oracle 和 MSSQL 数据库。这个错误只有在我们使用Oracle时才会出现,因为它是由oracle的BLOB实现引起的。
@lmetrak 发布了 KeystoreHelper.class 的和平。在这里我们没有交易。我们在上一步中为数据库获取了 Keystore 实体,我们关闭了事务并将实体传递给 KeystoreHelper class.
oracle.sql.BLOB 包含有关用于从数据库中获取实体的连接的信息。因此,当我们请求 BinaryStream 时,blob 会尝试连接到数据库以下载日期,因为它不仅仅是代理。它不会尝试从连接池中获取打开的连接,但会尝试使用用于获取密钥库实体的相同连接。有时会发生同时关闭连接,然后出现错误。我不确定什么是 MSSQL 策略,但他们的 BLOB 实现不包含有关连接的信息,因此不存在该问题。
我们的解决方案是将 Keystore.keystoreData 文件类型从 BLOB 更改为 byte[]。
现在它适用于 Oracle 和 MSSQL。
(...)
byte[] keystoreData = keystore.getKeystoreData();
/*A few checks*/
inputStream = new ByteArrayInputStream(keystore.getKeystoreData());
ByteArrayOutputStream outputStream= new ByteArrayOutputStream();
IOUtils.copy(inputStream , outputStream);
inputStream .close();
outputStream.close();
byte[] myKeystoreData = myBos.toByteArray();
inputStream = new ByteArrayInputStream(myKeystoreData);
(...)
我在从 Oracle 数据库接收 blob 字段时遇到了一个奇怪的问题:“SQLRecoverableException: Closed Connection
描述此异常的堆栈跟踪:
java.sql.SQLRecoverableException: Closed Connection
at oracle.jdbc.driver.OracleBlob.getDBAccess(OracleBlob.java:960) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.OracleBlob.getBinaryStream(OracleBlob.java:319) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.OracleBlob.getBinaryStream(OracleBlob.java:300) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.sql.BLOB.getBinaryStream(BLOB.java:316) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_221]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_221]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_221]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_221]
at org.hibernate.engine.jdbc.SerializableBlobProxy.invoke(SerializableBlobProxy.java:60) ~[hibernate-core-5.3.18.Final.jar:5.3.18.Final]
at com.sun.proxy.$Proxy142.getBinaryStream(Unknown Source) ~[?:?]
at com.xxx.yyy.util.KeystoreHelper.loadKeyStore(KeystoreHelper.java:89) [cphcore-3.23.0.23-SNAPSHOT.jar:?]
at com.xxx.yyy.bp.job.substep.ProcessIF2Files.getChannelUnsealer(IFB2UnsealFiles.java:207) [classes/:?]
at com.xxx.yyy.bp.job.substep.ProcessIF2Files.access(IFB2UnsealFiles.java:198) [classes/:?]
at com.xxx.yyy.bp.job.substep.ProcessIF2Files.execute(IFB2UnsealFiles.java:86) [classes/:?]
at com.xxx.yyy.bp.job.substep.ProcessIF2Files.execute(IFB2UnsealFiles.java:1) [classes/:?]
源代码:classKeystoreHelper方法loadKeyStore:
(...)
Blob keystoreBlob = keystore.getKeystoreData();
if (keystoreBlob == null || keystoreBlob.length() == 0) {
log.error("Keystore data is empty");
throw new KeystoreAccessException(keystore, "Keystore data is empty", null);
}
inputStream = keystore.getKeystoreData().getBinaryStream(); // line 89 - Exception
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
IOUtils.copy(inputStream, outputStream);
inputStream.close();
outputStream.close();
byte[] keystoreData = outputStream.toByteArray();
inputStream = new ByteArrayInputStream(keystoreData);
(...)
变量的源代码 - 密钥库,class DbKeystore(实体),方法 getKeystoreData:
(...)
private java.sql.Blob keystoreData;
public java.sql.Blob getKeystoreData() {
return this.keystoreData;
}
public void setKeystoreData(java.sql.Blob keystoreData) {
this.keystoreData = keystoreData;
}
(...)
大家遇到过类似的问题吗? 感谢您的帮助:)
这很可能是由于底层 JDBC 连接被放回连接池造成的。确保用于加载实体的 EntityManager
或 Session
在您访问 blob 时仍然处于活动状态。
我正在与@lmetrak 一起工作,最后我弄清楚出了什么问题。 我们的应用程序支持 Oracle 和 MSSQL 数据库。这个错误只有在我们使用Oracle时才会出现,因为它是由oracle的BLOB实现引起的。
@lmetrak 发布了 KeystoreHelper.class 的和平。在这里我们没有交易。我们在上一步中为数据库获取了 Keystore 实体,我们关闭了事务并将实体传递给 KeystoreHelper class.
oracle.sql.BLOB 包含有关用于从数据库中获取实体的连接的信息。因此,当我们请求 BinaryStream 时,blob 会尝试连接到数据库以下载日期,因为它不仅仅是代理。它不会尝试从连接池中获取打开的连接,但会尝试使用用于获取密钥库实体的相同连接。有时会发生同时关闭连接,然后出现错误。我不确定什么是 MSSQL 策略,但他们的 BLOB 实现不包含有关连接的信息,因此不存在该问题。
我们的解决方案是将 Keystore.keystoreData 文件类型从 BLOB 更改为 byte[]。 现在它适用于 Oracle 和 MSSQL。
(...)
byte[] keystoreData = keystore.getKeystoreData();
/*A few checks*/
inputStream = new ByteArrayInputStream(keystore.getKeystoreData());
ByteArrayOutputStream outputStream= new ByteArrayOutputStream();
IOUtils.copy(inputStream , outputStream);
inputStream .close();
outputStream.close();
byte[] myKeystoreData = myBos.toByteArray();
inputStream = new ByteArrayInputStream(myKeystoreData);
(...)