[Seasar-user:18707] Re: [S2DBCP] DB再起動後のコネクション取得について

Satou Mamoru [E-MAIL ADDRESS DELETED]
2009年 10月 21日 (水) 00:29:01 JST


小林さま、瀧口さま

佐藤です。
回答ありがとうございます。

>瀧口さま

私の環境でも Postgres の JDBCドライバを使っています。
バージョンもほぼ同じです。

DB: PostgreSQL 8.3.7 (OSはLinux)
JDBC: postgresql-8.3-604-jdbc4.jar

小林さまに調べていただいた結果、こちらの設定ミスが原因であれば
よいのですが、そうでない場合、もしよろしければどのように回避されたか、
ご教授いただけないでしょうか。

>小林さま

以下の2つのログを取得しました。SQLやスタックトレースは
省略させていただきました。

・DBを再起動せず、DBアクセスが成功する場合

DEBUG org.seasar.extension.jta.TransactionImpl
トランザクションを開始しました。tx=[FormatId=4360, GlobalId=1256003912995/8,
BranchId=]
DEBUG org.seasar.extension.jdbc.query.AutoSelectImpl select ...
DEBUG org.seasar.extension.dbcp.impl.ConnectionPoolImpl
論理的なコネクションを取得しました。tx=[FormatId=4360, GlobalId=1256003912995/8,
BranchId=]
DEBUG org.seasar.extension.jta.TransactionImpl
トランザクションをコミットしました。tx=[FormatId=4360, GlobalId=1256003912995/8,
BranchId=]
DEBUG org.seasar.extension.dbcp.impl.ConnectionWrapperImpl
論理的なコネクションを閉じました。tx=[FormatId=4360, GlobalId=1256003912995/8,
BranchId=]

・DBを再起動して、DBアクセスが失敗する場合

DEBUG org.seasar.extension.jta.TransactionImpl
トランザクションを開始しました。tx=[FormatId=4360, GlobalId=1256003912995/9,
BranchId=]
DEBUG org.seasar.extension.jdbc.query.AutoSelectImpl select ...
DEBUG org.seasar.extension.dbcp.impl.ConnectionPoolImpl
論理的なコネクションを取得しました。tx=[FormatId=4360, GlobalId=1256003912995/9,
BranchId=]
DEBUG org.seasar.framework.aop.interceptors.TraceInterceptor END
XXXService#findById(1)
Throwable:org.seasar.framework.exception.SQLRuntimeException:
[ESSR0072]SQLで例外(SQL=[select ...],
Message=[[ESSR0072]SQLで例外(SQL=[select ...], Message=[0],
ErrorCode=08006, SQLState={3})が発生しました : [SQLで例外(Message=[An I/O error
occured while sending to the backend.], ErrorCode=0,
SQLState=08006)が発生しました。], [An I/O error occured while sending to the
backend.], [Connection reset by peer: socket write error],
ErrorCode=0, SQLState=08006)が発生しました
DEBUG org.seasar.extension.jta.TransactionImpl
トランザクションをロールバックしました。tx=[FormatId=4360, GlobalId=1256003912995/9,
BranchId=]
DEBUG org.seasar.extension.dbcp.impl.ConnectionWrapperImpl
論理的なコネクションを閉じました。tx=[FormatId=4360, GlobalId=1256003912995/9,
BranchId=]

このログが出力される前にDBアクセスを行っているため、物理的なコネクションは取得済みの状態です。
また、DB再起動でなく、DBを停止して動作をさせてもDB再起動と同じログ及び同じ結果となりました。

SQLを発行する直前(論理的なコネクションを取得する直前)のプールの状態は
以下のようでした。

ActivePoolSize:0
TxActivePoolSize:0
FreePoolSize:1

例外発生後の処理の流れをデバッガで追っていくと、瀧口さまが書かれた動きを
しているように見えました(最終的にcheckInFreePool()が呼び出されていた)。
トランザクション属性はデフォルトのRequiredです。
COOL Deployで確認しております。

よろしくお願いいたします。

2009年10月20日23:30 Koichi Kobayashi <[E-MAIL ADDRESS DELETED]>:
> 小林 (koichik) です.
>
> Date:    Tue, 20 Oct 2009 22:54:18 +0900
> From:    takiguchi <[E-MAIL ADDRESS DELETED]>
> To:      [E-MAIL ADDRESS DELETED]
> Subject: [Seasar-user:18703] Re: [S2DBCP] DB再起動後のコネクション取得について
>
>> >S2DBCP では,例外が発生したコネクションは
>> >プールに戻さないようになっています.
>> というのは正確ではなく、実際には
>> 例外が発生した場合のロールバックで例外が発生したコネクションはプールに戻さない、
>> という動きになっています。
>> 実際のコードですと、TransactionImpl#rollbackResources で、
>> ロールバックで例外が発生した場合に status に Status.STATUS_UNKNOWN を、
>> それ以外の場合 Status.STATUS_ROLLEDBACK を設定しています。
>> この status の値が ConnectionPoolImpl.SynchronizationImpl#afterCompletion に渡され、
>> STATUS_COMMITTED か STATUS_ROLLEDBACK の場合 ConnectionPoolImpl#checkInTx が呼ばれています。
>
> それ以前に,例えば prepareStatement() 等で
> 本来のコネクションが例外をスローすると,
> ConnectionWrapperImpl#release() 経由で
> ConnectionPoolImpl#release() が呼ばれ,
> コネクションはプールから除去されます.
>
>        activePool.remove(connection);
>        Transaction tx = getTransaction();
>        if (tx != null) {
>            txActivePool.remove(tx);
>        }
>
> なので,ロールバックにおいて
> ConnectionPoolImpl#checkInTx() が呼び出されても,
> 該当のコネクションはプールに含まれていないため,
> ConnectionPoolImpl#checkInFreePool() に
> 制御が渡ることはありません.
>
>        ConnectionWrapper con = (ConnectionWrapper) txActivePool.remove(tx);
>        if (con == null) {
>            return;
>        }
>        checkInFreePool(con);
>
> よって,コネクションがプールに戻ることは
> ないはずです.
>
> 実際にコネクションがプールに戻るなら,
> ロールバック時の問題ではなく,最初に例外が
> 発生した時点で想定外の状況になっているように
> 思われます.
> トランザクション開始時からの一連のログを
> 見せていただけないでしょうか.
>
>
> --
> <component name="koichik">
>    <property name="fullName">"Koichi Kobayashi"</property>
>    <property name="email">"[E-MAIL ADDRESS DELETED]"</property>
>    <property name="blog">"http://d.hatena.ne.jp/koichik"</property>
> </component>
>
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user
>


Seasar-user メーリングリストの案内