无法将T4CConnection强制转换为oracle.jdbc.OracleConnection

本文详细介绍了在尝试将T4CConnection强制转换为OracleConnection时遇到的问题及解决方案。通过使用isWrapperFor和unwrap方法,成功解决了连接池包装器导致的类型转换失败,确保了对Oracle数据库表注释的正确读取。

无法将T4CConnection连接强制转换为oracle.jdbc.OracleConnection

问题描述

项目中需要获取oracle数据库中字段的注释,原来代码如下

// 设置Oracle数据库的表注释可读
if (conn instanceof OracleConnection) {
// 设置连接属性,使得可获取到表的REMARK(备注)
			((OracleConnection) conn).setRemarksReporting(true);
		};

打断点发现conn为 oracle.jdbc.driver.T4CConnection

问题解决

// 设置Oracle数据库的表注释可读
if (conn instanceof OracleConnection) {
// 设置连接属性,使得可获取到表的REMARK(备注)
			((OracleConnection) conn).setRemarksReporting(true);
		} else {
			try {
				// T4CConnection不能instanceof OracleConnection
				if (conn.isWrapperFor(OracleConnection.class)) {
					OracleConnection oracleConnection = conn.unwrap(OracleConnection.class);
					oracleConnection.setRemarksReporting(true);
				}
			} catch (SQLException e) {
				log.error("handleRemarks" + e);
			}
		}

问题原因

连接池通常在真实的连接实例周围有一个包装器,这就是您的强制转换失败的原因。
也可以通过反射进行解决。

java.sql.SQLException: Listener refused the connection with the following error: ORA-12505, TNS:listener does not currently know of SID given in connect descriptor (CONNECTION_ID=x7umTu2wQtmPZyHo5lJNEw==) at oracle.jdbc.driver.T4CConnection.handleLogonNetException(T4CConnection.java:870) at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:675) at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:1032) at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:90) at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:681) at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:602) at com.fr.third.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1666) at com.fr.third.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1732) at com.fr.third.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2907) Caused by: oracle.net.ns.NetException: Listener refused the connection with the following error: ORA-12505, TNS:listener does not currently know of SID given in connect descriptor (CONNECTION_ID=x7umTu2wQtmPZyHo5lJNEw==) at oracle.net.ns.NSProtocolNIO.createRefusePacketException(NSProtocolNIO.java:816) at oracle.net.ns.NSProtocolNIO.handleConnectPacketResponse(NSProtocolNIO.java:396) at oracle.net.ns.NSProtocolNIO.negotiateConnection(NSProtocolNIO.java:207) at oracle.net.ns.NSProtocol.connect(NSProtocol.java:350) at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1967) at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:640) ... 7 more
07-08
`locked (a oracle.jdbc.driver.T4CConnection)` 表明 `oracle.jdbc.driver.T4CConnection` 处于锁定状态,可能由事务未正常结束、资源未正确释放或数据库层面的锁定等原因导致。 对于事务未正常结束的情况,若一个事务开始后没有正常提交或回滚,数据库连接会一直被占用,从而造成连接锁定。例如以下代码未提交或回滚事务: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; public class TransactionExample { public static void main(String[] args) { try { Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL", "username", "password"); conn.setAutoCommit(false); Statement stmt = conn.createStatement(); stmt.executeUpdate("UPDATE table_name SET column1 = 'value' WHERE id = 1"); // 未提交或回滚事务 // conn.commit(); // conn.rollback(); } catch (Exception e) { e.printStackTrace(); } } } ``` 解决此问题,可使用 `try-catch-finally` 结构确保事务正常结束: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; public class TransactionFixExample { public static void main(String[] args) { Connection conn = null; try { conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL", "username", "password"); conn.setAutoCommit(false); Statement stmt = conn.createStatement(); stmt.executeUpdate("UPDATE table_name SET column1 = 'value' WHERE id = 1"); conn.commit(); } catch (Exception e) { if (conn != null) { try { conn.rollback(); } catch (Exception ex) { ex.printStackTrace(); } } e.printStackTrace(); } finally { if (conn != null) { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } } } } } ``` 资源未正确释放也会导致连接被锁定。若使用完数据库连接、语句或结果集后未正确关闭,会造成资源泄漏,连接可能被锁定。例如以下代码未关闭资源: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class ResourceLeakExample { public static void main(String[] args) { try { Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL", "username", "password"); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM table_name"); // 未关闭资源 // rs.close(); // stmt.close(); // conn.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 可使用 `try-with-resources` 语句确保资源使用完后自动关闭: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class ResourceReleaseExample { public static void main(String[] args) { try (Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL", "username", "password"); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM table_name")) { while (rs.next()) { // 处理结果集 } } catch (Exception e) { e.printStackTrace(); } } } ``` 若为数据库层面的问题,需检查数据库状态。可使用 Oracle 的系统视图查看当前的锁定情况,如 `V$LOCK` 和 `V$SESSION` 视图: ```sql SELECT s.sid, s.serial#, l.type, l.id1, l.id2, l.lmode, l.request FROM v$lock l, v$session s WHERE l.sid = s.sid; ``` 根据查询结果,可找出锁定的会话并采取相应措施,如终止会话等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值