java.sql.SQLRecoverableException: Closed Connection エラーへの対応
プラットフォームについて: Server および Data Center のみ。この記事は、Server および Data Center プラットフォームのアトラシアン製品にのみ適用されます。
Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.
*Fisheye および Crucible は除く
問題
atlassian-confluence.log
に次の例のようなエラーが表示されることがあります。
2020-06-04 12:58:39,068 ERROR [http-nio-26136-exec-9] [engine.jdbc.spi.SqlExceptionHelper] logExceptions Cannot close connection (invalidating pooled object failed)
-- url: /c6136/admin/dobackup.action | traceId: 7cfdc86875a87aa1 | referer: http://localhost:26136/c6136/admin/backup.action
2020-06-04 12:58:39,106 ERROR [http-nio-26136-exec-9] [[Standalone].[localhost].[/c6136].[action]] log Servlet.service() for servlet [action] in context with path [/c6136] threw exception
org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is net.sf.hibernate.TransactionException: Unable to commit against JDBC Connection
at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:514)
at com.atlassian.confluence.impl.hibernate.ConfluenceHibernateTransactionManager.doCommit(ConfluenceHibernateTransactionManager.java:69)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:765)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:734)
(...)
Caused by: net.sf.hibernate.TransactionException: Unable to commit against JDBC Connection
at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.commit(AbstractLogicalConnectionImplementor.java:85)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:221)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68)
at com.atlassian.hibernate.util.TransactionHelper$RestartOnCommitTransaction.commit(TransactionHelper.java:45)
at com.atlassian.hibernate.adapter.adapters.TransactionV2Adapter.commit(TransactionV2Adapter.java:30)
at org.springframework.orm.hibernate.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:510)
... 204 more
Caused by: java.sql.SQLRecoverableException: Closed Connection
at oracle.jdbc.driver.PhysicalConnection.getAutoCommit(PhysicalConnection.java:1828)
at oracle.jdbc.driver.PhysicalConnection.commit(PhysicalConnection.java:1905)
at oracle.jdbc.driver.PhysicalConnection.commit(PhysicalConnection.java:1942)
at org.apache.tomcat.dbcp.dbcp2.DelegatingConnection.commit(DelegatingConnection.java:358)
at org.apache.tomcat.dbcp.dbcp2.DelegatingConnection.commit(DelegatingConnection.java:358)
at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.commit(AbstractLogicalConnectionImplementor.java:79)
上記の例は Oracle データベースの利用時に発生しています。同じ種類のデータベースで次のような出力が返されることもあります。
java.sql.SQLException: Closed Connection at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
at oracle.jdbc.driver.PhysicalConnection.rollback(PhysicalConnection.java:1170)
at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.rollback(DelegatingConnection.java:368)
at org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.rollback(PoolingDataSource.java:323)
at net.sf.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:86)
at org.springframework.orm.hibernate.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:529)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:753)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:730)
at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.j
これらは、Confluence データベースのトランザクション中に一定期間非アクティブ状態になったときに発生することがあります。例として、Confluence の XML バックアップの実行があります。
原因
このエラー メッセージは、バックアップ タスク (または単一のデータベース コネクションに依存する他の長期実行処理) で利用されているコネクションが、トランザクションの実行中にクローズされたことを意味します。原因にはさまざまなものが考えられます。たとえば、ファイアウォール、ネットワーク デバイス、リモート データベース リスナーなどの外部デバイスが、一定の非アクティブ (アイドル) 期間やコネクションがオープンだった長さ (TTL) に応じてネットワーク コネクションを強制的にクローズする可能性があります。
この種の状況が発生すると、データベース コネクション プール (DBCP) や C3PO (JDBC を直接利用している場合) でコネクションの終了を検知することができません。Confluence がプールのコネクションを利用しようとした時点でのみ、"Closed Connection" の例外が返されます。
考えられる解決策
Oracle データベースの設定の確認
データベース管理者がデータベース (この例では Oracle) 側で、コネクションのクローズにつながる可能性のある構成を確認します。詳細については次のページをご確認ください。
Linux オペレーション システムの設定の確認
XML バックアップ ジョブの場合、データベース コネクション プールにある 1 つのコネクションを利用し、ジョブの終了時までそれを使います。コネクションがプールに存在しなくなっており、トランザクションの終了時まではアイドル状態であるため、c3p0.idle_test_period プロパティによる検証が行われず、ファイアウォール (または他のネットワーク コンポーネント) のタイムアウトでワイプアウトされる可能性があります。
この場合、オペレーション システム側 (Confluence のサーバー/ノード) の tcp_keepalive_time 設定に、データベース トランザクションが中断なしで実行できるような値が設定されていることを確認します。詳細については次のページをご確認ください。
検証クエリが構成されていることを確認
データベースへの検証クエリの追加について「コネクションのクローズに対応する」をご確認ください。これにより、データソース接続でコネクションが利用可能であると判断して提供する前に、データベースに対して検証クエリを実行できます。
追加の接続プロパティとして、jdbc バージョン < 10.1.0.5 では 'oracle.net.READ_TIMEOUT=5000' を、jdbc バージョン >=10.1.0.5
では oracle.jdbc.ReadTimeout=5000' をリソース定義に追加します。
次の内容は Oracle データベース専用です。
<Resource name="jdbc/ConfluenceDS"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@my.host.edu:PORT:SID"
username="***MASKED***"
password="***MASKED***"
connectionProperties="SetBigStringTryClob=true; oracle.net.READ_TIMEOUT=5000;"
maxActive="20"
maxIdle="10"
maxWait="-1"
validationQuery="select 1 from dual"
/>
個々のプール設定で最大コネクション期間を確認
- データベースへの JNDI データソース コネクション (https://ja.confluence.atlassian.com/doc/configuring-a-datasource-connection-937166084.html) で、Tomcat の server.xml で以降のプロパティが構成されている場合はそれらを確認します。
- removeAbandoned および removeAbandonedTimeout。デフォルトでは、Tomcat 配下の removeAbandoned プロパティは false に設定されていますが、これが true に設定されているインスタンスでは、removeAbandonedTimeout で設定された値に基づいてコネクションが無視される可能性があります。removeAbandonedTimeout のデフォルト値は 60 秒であり、1 分の非アクティブ期間が発生するとコネクションが無視されます。この状態で、処理に 1 分以上かかるタスクがある場合、コネクションで Closed Connection エラーが発生する可能性があります。これらのプロパティの詳細については次のページをご確認ください。https://tomcat.apache.org/tomcat-9.0-doc/jdbc-pool.html
- データベースへの直接 JDBC 接続 (デフォルトのセットアップ) で、confluence.cfg.xml ファイルで次のプロパティが構成されている場合はそれらを確認します。
- maxConnectionAge - ここで構成されている値に応じ、データベースから取得された任意のコネクションがコネクションの初期化以降にこの値を超過すると、プールでコネクションの利用状況が取り除かれます。上記のとおり、これも Closed Connection 例外を発生させる可能性があります。詳細については次のページをご確認ください。https://www.mchange.com/projects/c3p0/#managing_pool_size