这是对连接池的不正确使用。您永远不应调用
close()未包装的连接。
使用池连接的正常流程是
- 获取
Connection
,池获得物理连接并返回包装在其自己的包装器中的包装 - 您使用
Connection
- 你叫
close()
的Connection
。这实际上并没有 关闭 任何内容,池的包装程序拦截了该close()
调用,并仅将(仍处于活动状态的)连接返回到池。
之所以有效,是因为该池具有包装器类,
PoolableConnection即that
implementsConnection。
PoolableConnection委托底层连接来执行实际工作,但是(除其他事项外)实现方式
close()有所不同。这将破坏当前的
PoolableConnection包装,并将底层组件返回
Connection到连接池。例如。
这样,您的程序逻辑就可以从中获取连接,然后
DataSource使用
Connection和
close(),就像正常的非池化一样
Connection。
正是这种透明性使连接池易于使用。
现在,当您调用时
unwrap,
PooledConnection您就可以访问它的内部真实
Connection委托。
什么 ,你 要做的就是调用
close()的委托 !
这有两个效果:
- 它不叫
close()
上PooledConnection
,所以在Connection
没有得到返回到池中。 - 它关闭了池底的底层连接。这不应该成为问题,因为池本身将处理掉线的连接。
因此,您需要非常小心。 总是 叫
close()上
Connection你已经从池中得到,将其返回到池中。 永远不要
调用
close()基础连接。
因此,您的代码应为:
try (final Connection poolConn = DataSourceConnectionPool.getConnection()) { final Connection conn = poolConn.unwrap(OracleConnection.class); //do stuff with conn //do not close conn!!}//poolConn is returned to the pool


