2006年,我为Oracle连接编写了自己的JDBC连接池。 我将这些集合存储在一个Vector中,每天晚上我实例化一个新的Vector对象来初始化连接池:
connections = new Vector(poolsize);
因此,所有现有连接都被垃圾收集器删除,而Oracle删除了连接。
说实话,这是一个非常糟糕的解决方案-但是它可以工作12年而没有问题!
今年,我们将Oracle版本更新为12.2.0.1.0,并在高级程序中更新了Oracle-JDBC驱动程序。
我当前正在使用从以下网站下载的Oracle Database 12.2.0.1 JDBC驱动程序(ojdbc8.jar):
https://www.oracle.com/technetwork/database/features/jdbc/jdbc-ucp-122-3110062.html
数据库访问工作正常-除了我的连接池不足之外。 在调用“ connections = new Vector(poolsize)”之后,Oracle-DB不会删除打开的连接,打开的JDBC连接的数量每天都会增加-直到Oracle崩溃(打开的JDBC连接太多)。
我知道我必须使用close()关闭每个JDBC连接,而不是仅初始化保存集合的Vector。 但是我想知道为什么新的Oracle JDBC驱动程序在垃圾回收运行后没有删除所有连接。
这是新的JDBC驱动程序的错误吗?
在所有较旧的JDBC驱动程序中,不会发生此错误-仅在新的ojdbc8.jar中发生。
如果无法访问,则JDBC驱动程序应自动关闭所有与数据库相关的对象(例如ResultSet)。 我不相信每个JDBC开发人员都会在数据库操作完成后关闭ResultSet对象。 我尚未测试ojdbc8.jar是否将关闭这些未关闭的ResultSet-Objects,但是如果没有,将来某些程序将崩溃。
您怎么看,新的JDBC驱动程序中是否存在错误,因为无法访问的JDBC连接没有自动关闭?
答案 0 :(得分:2)
您应该切换到经过良好测试的共享库,例如HikariCP。有很多陷阱,例如回滚后如何正确重置连接,请参见Pool Analysis或Bad Behavior: Handling Database Down。自己编写和维护此代码会适得其反。
答案 1 :(得分:0)
不是每个 JDBC开发人员都会关闭资源,但是每个好开发人员都会关闭资源。
如果池中有连接,则很容易达到它们。这意味着它们不会被GC调用,并且不会调用会释放资源的finalize()
方法(如果驱动程序的类中存在)。
不要首先责怪驱动程序,它们往往会像您的代码一样经过严格测试。
答案 2 :(得分:0)
您可以使用通用连接池(UCP),它是Java连接池。请参阅UCPSample.java。另外,有关更多详细信息,请参见UCP Developer's guide。