簡體   English   中英

HikariCP NullPointerException

[英]HikariCP NullPointerException

我們正在嘗試將HikariCP(版本2.4.4)集成到我們的應用程序中。 使用一段時間后,池無法獲取新的連接拋出:

    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驅動程序是ojdbc-7,版本為12.1.0.2。 池使用以下配置:

    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

是錯誤還是配置錯誤?

我不確定100%,但看起來像是:

  • 在調用close()之后,您將退出連接,這是不允許的。 要么..
  • 您正在逐出連接,然后調用close() ,這是不允許的。

退出連接時,您必須是該連接的所有者(從getConnection()獲得,並且隨后您必須不close()連接(它將自動關閉)。如上所述,如果調用了close()已經存在,則該連接已經返回到池中,因此將其逐出是無效的,因為您不再是所有者。

編輯:讓我更清楚。 通過研究如何實現此異常,您似乎很清楚,首先要關閉連接,然后逐出連接。 反向(先退出然后關閉)不會導致此錯誤。

這稱為“返回后使用”,類似於沒有垃圾回收的語言中的“免費使用后”錯誤。 關閉連接后,它會返回到池中。 從那一刻起,該連接就可以被另一個線程聲明了-close close()的調用者不再是所有者。

這完全類似於在C / C ++中在內存上調用free() 這樣做之后,立即可以由另一個調用方聲明該內存-free free()的調用方不再是所有者。 在C / C ++情況下,如果繼續使用對釋放的內存的引用,則可能會損壞已分配該內存的另一個線程的數據。

對於Java中幾乎所有的池庫(連接或其他),一旦將對象釋放回池中,您就不再是所有者。 沒有什么可以阻止您保留對返回對象的引用。

在這種情況下,一旦調用close() ,該對象將立即返回到池中。 如果另一個線程從池( getConnection() )合法獲取連接,而同時先前的所有者調用evict() ,則您很容易遇到此問題。

我們可以選擇強化(或不強化)此代碼路徑。 HikariCP在哲學上並不是特別的家長式管理。 偏愛文檔而不是代碼。 例如,如果將null傳遞給evict() ,則在某處會遇到NPE。 我們可以檢查null並忽略它嗎? 當然。 在整個代碼庫中乘以該方法,它很容易增長20%。 或者,不這樣做,開發人員呢?

這是一個相當簡單的合同:

  • 您只能逐出您擁有的連接。
  • 關閉連接后,您將不再擁有該連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM