4

わかりました、ここで奇妙なものを手に入れました。マルチテナンシー用に構成された休止状態と接続プール用の C3P0 を使用するアプリケーションをセットアップしています。

ログで例外がスローされ、その原因を突き止めることができないことを除いて、すべてが正常に機能します...奇妙なことは、この例外が私のアプリケーションを決して悩ませず、例外がスローされても正常に動作していることです(常に 4 回、何もせずにサーバーを起動して待つ場合でも、数秒後にログにポップアップ表示され、それだけです)

例外と役立つ可能性のあるいくつかの基本的な構成を次に示します。

2013-05-28 09:06:02 WARN  BasicResourcePool:1841 - com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@1d926e41 -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception: 
com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'dbuser'. ClientConnectionId:07fa33fd-9de8-4235-b991-ac7e9e1ad437
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
    at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:254)
    at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:84)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:2908)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:2234)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.access$000(SQLServerConnection.java:41)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:2220)
    at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1326)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:991)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:827)
    at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)
    at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
    at com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32)
    at com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

セッションファクトリー:

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="annotatedClasses">
        <list>
            ...
        </list>
    </property>
    <property name="hibernateProperties">
        <value>
            hibernate.multiTenancy=SCHEMA
            hibernate.tenant_identifier_resolver=xxx.xxx.hibernate.CurrentTenantIdentifierResolverImpl
            hibernate.multi_tenant_connection_provider=xxx.xxx.hibernate.MultiTenantConnectionProviderImpl

            hibernate.dialect=${hibernate.dialect}
            hibernate.use_sql_comments=${hibernate.debug}
            hibernate.show_sql=${hibernate.debug}
            hibernate.format_sql=${hibernate.debug}
        </value>
    </property>
</bean>

c3p0-config.xml:

<c3p0-config> 
    <named-config name="c3p0name">  
        <property name="acquireIncrement">3</property>
        <!--property name="automaticTestTable">con_test</property--> 
        <property name="checkoutTimeout">30</property> 
        <property name="idleConnectionTestPeriod">30</property> 
        <property name="initialPoolSize">2</property> 
        <property name="maxIdleTime">18000</property> 
        <property name="maxPoolSize">30</property> 
        <property name="minPoolSize">2</property> 
        <property name="maxStatements">50</property>
        <property name="testConnectionOnCheckin">true</property>
    </named-config>
</c3p0-config>

ConnectionPool をインスタンス化する実装は次のとおりです。

public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider  {


    private static final long serialVersionUID = 8074002161278796379L;

    ComboPooledDataSource cpds;

    public MultiTenantConnectionProviderImpl() throws PropertyVetoException {
        cpds = new ComboPooledDataSource("c3p0name");
        cpds.setDriverClass("jdbc.driver"));
        cpds.setJdbcUrl("jdbc.url"));
        cpds.setUser("dbuser");
        cpds.setPassword("dbuserpassword"));
    }


    @Override
    public Connection getAnyConnection() throws SQLException {
        return cpds.getConnection();
    }

    @Override
    public Connection getConnection(String dbuser) throws SQLException {
        return cpds.getConnection(dbuser, PropertyUtil.getCredential(dbuser));
    }

直接的な回答が得られなくても、私の調査に役立つ可能性のある意見や指示があれば喜んでお答えします。前もって感謝します

編集:

DBConnectionPool の password プロパティの dbuserpassword の構成ミスにすぎない、初期接続の失敗に関するエラーが手元にあることがわかりました。

これは質問の一部を解決し、最初は重複のみを残します.@Steve Waldmanからの回答の下の議論に従うと、log4jの設定ミスである可能性が最も高いです.

4

1 に答える 1

4

常に4回、何もせずにサーバーを起動して待つだけです。

したがって、サーバーの再起動時にこれが観察されることを考えると、それについて特に奇妙なことは何もありません。サーバーがダウンして再起動している間、c3p0 はデータベース接続の取得を試みますが失敗します。最終的に (デフォルトでは ~30 秒後)、c3p0 は失敗を宣言し、表示された例外をログに記録し、接続でスレッドの wait()ing にエラーを通知します。サーバーの再起動には 30 秒以上かかるようです。

これが 4 回表示されるということは、おそらく 4 つのアクティブな接続プールがあることを意味します。つまり、アクティブな 4 つの異なる dusers (デフォルト ユーザーを含む) があることを意味します。各 c3p0 DataSource は、認証資格情報のセットごとに 1 つずつ、複数のプールを管理する可能性があります。

これらのメッセージを消したい場合は、c3p0 が取得の失敗を宣言するのにかかる時間を増やしてください。hereおよびacquireRetryAttemptsacquireRetryDelayを参照してください。再起動中にクライアントに時折 SQLException がスローされるのを防ぎたい場合は、現在 30 秒に設定されているクライアントのタイムアウトcheckoutTimeoutを長くします。

その他のコメント: 遅いデフォルトの接続テストを使用しています。自動テストテーブルを試してみましたが、元に戻しました。preferredTestQueryを設定してみてください。ここで SQL Server に推奨されているように、SELECT 1 だけで十分かもしれません。すべての接続テストを非同期で行っているため、これはあまり問題にならないかもしれませんが、少なくともテストのオーバーヘッドを削減できる可能性があります。

幸運を!

于 2013-05-28T10:07:48.067 に答える