首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HikariCP NullPointerException

HikariCP NullPointerException
EN

Stack Overflow用户
提问于 2016-03-07 09:54:51
回答 1查看 2.1K关注 0票数 0

我们正在尝试将HikariCP (版本2.4.4)集成到我们的应用程序中。在使用了一段时间之后,池无法获得新的连接,引发:

代码语言:javascript
复制
    java.lang.NullPointerException
        at com.zaxxer.hikari.pool.PoolBase.setNetworkTimeout(PoolBase.java:464) ~[HikariCP-2.4.4.jar:?]
        at com.zaxxer.hikari.pool.PoolBase.isConnectionAlive(PoolBase.java:131) ~[HikariCP-2.4.4.jar:?]
        at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:171) ~[HikariCP-2.4.4.jar:?]
        at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:147) ~[HikariCP-2.4.4.jar:?]
        at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:83) ~[HikariCP-2.4.4.jar:?]

我们使用的jdbc驱动程序是版本12.1.0.2的ojdbc-7。池使用以下配置:

代码语言:javascript
复制
    allowPoolSuspension.............false
    autoCommit......................false
    catalog.........................null
    connectionInitSql..............."BEGIN EXECUTE IMMEDIATE 'SET ROLE SOME_ROLE IDENTIFIED BY SOME_PASSWORD '; END;"
    connectionTestQuery............."SELECT 1 FROM DUAL"
    connectionTimeout...............15000
    dataSource......................null
    dataSourceClassName.............null
    dataSourceJNDI..................null
    dataSourceProperties............{v$session.machine=host, password=<masked>, v$session.program=my application}
    driverClassName................."oracle.jdbc.OracleDriver"
    healthCheckProperties...........{}
    healthCheckRegistry.............null
    idleTimeout.....................60000
    initializationFailFast..........true
    isolateInternalQueries..........false
    jdbc4ConnectionTest.............false
    jdbcUrl........................."jdbc:oracle:thin:@//host.company.com:1521/database.company.com"
    leakDetectionThreshold..........1800000
    maxLifetime.....................0
    maximumPoolSize.................18
    metricRegistry..................null
    metricsTrackerFactory...........null
    minimumIdle.....................2
    password........................<masked>
    poolName........................"TEST_POOL"
    readOnly........................false
    registerMbeans..................false
    scheduledExecutorService........null
    threadFactory...................null
    transactionIsolation............null
    username........................"USER_NAME"
    validationTimeout...............5000

是错误还是错误配置?

EN

回答 1

Stack Overflow用户

发布于 2016-03-07 12:14:39

我不是百分之百确定,但看起来

  • 在调用close()之后,您正在取消一个连接,这是不允许的。或者..。
  • 您正在取消一个连接,然后调用close(),这是不允许的。

当您退出一个连接时,您必须是该连接的所有者(从getConnection()获得,随后您不能close()该连接(它将自动关闭)。正如上面所解释的,如果您已经调用了close(),则连接已经返回到池中,并且由于您不再是所有者,因此驱逐它是无效的。

编辑:让我说得更清楚。通过研究如何达到此异常,似乎可以清楚地看到,您首先要关闭连接,其次是取消连接。反向(驱逐,然后关闭)不会导致此错误。

这被称为“返回后使用”,类似于在没有垃圾收集的语言中“使用后免费”的bug。当您关闭连接时,它将返回到池中。从那一刻起,连接就可以由另一个线程声明-- close()的调用者不再是所有者。

这与调用C/C++中的内存中的free()完全类似。在这样做之后,内存就可以被另一个调用方调用-- free()的调用者不再是所有者了。在C/C++情况下,如果您继续使用对已释放内存的引用,则可能会破坏另一个已分配它的线程的数据。

在Java中几乎所有池库(连接或其他)的情况下,一旦将对象释放回池,您就不再是所有者。没有什么可以阻止您保留对返回对象的引用。

在这种情况下,一旦调用了close(),对象就会立即返回到池中。如果另一个线程合法地从池(getConnection())获得连接,而前面的所有者同时调用evict(),则很容易遇到此问题。

我们可以选择加强这个代码路径(或不)。HikariCP在哲学上并不是特别家长式的,它更倾向于文档而不是代码。例如,如果您将一个null传递给evict(),您将在某个地方遇到一个NPE。我们能检查一下null并忽略它吗?好的。将这一方法乘以代码基,它很容易增长20%。或者,不要那样做,开发人员?

这是一个相当简单的合同:

  • 你只能驱逐你所拥有的联系。
  • 一旦你关闭了连接,你就不再拥有它。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35840631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档