2

Java ライブラリ C3PO を使用して、MySQL データベースで接続プールを実装しています。接続リークを特定するために、クエリの前後に接続をログに記録しています。使用すべきではないときに、ほぼ 20 の接続を使用する 1 つのクエリを見つけました。実際、MySQL プロセスリストを確認すると、50 個の新しいプロセスが作成されています。これにより、バックエンドがデータベースへの接続を取得できなくなるため、webapp 全体が失敗します。

リークを引き起こすメソッドの疑似コードを次に示します。

public List<Interaction> getInteractions() {
     // Log the # of connections before the query
     logNumConnections();
     --> stdout: Total (7) Idle: (2) Busy: (5) Orphan: (0)

     // Here's the query that's causing the leak
     String sql="select distinct ... from A left join B on A.x=B.y "
            + "where A.x in (?,?,...)"
     List<Interaction> results = jdbcTemplate.query(sql, args, rowMapper);

     // Log the # connections after the query
     logNumConnections();
     --> stdout: Total (24) Idle: (0) Busy: (24) Orphan: (0)

     return results;
}

JdbcTemplate は、接続を閉じてリソースを解放することになっています。1 つのクエリで 20 の接続を使用するべきではありません。これらの接続は、クエリの後も長く残ります。これが私の JdbcTemplate と DataSource の構成です。

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
     <property name="driverClass" value="${database.driver}" />
     <property name="jdbcUrl" value="${database.url}"/>
     <property name="user" value="${database.username}"/>
     <property name="password" value="${database.password}"/>
     <property name="initialPoolSize" value="5" />
     <property name="minPoolSize" value="5" />
     <property name="maxPoolSize" value="50" />
     <property name="acquireIncrement" value="1" />
     <property name="maxStatements" value="1000" />
     <property name="maxStatementsPerConnection" value="1000"/>
     <property name="maxIdleTime" value="10000"/>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
     <constructor-arg>
          <ref bean="dataSource" />
     </constructor-arg>
</bean>

explain最後に発表文はこちら

id|select_type|table|type  |possible_keys|key    |key_len|rows  | Extra  
 1|SIMPLE     |A    |ALL   |NULL         |NULL   |NULL   |437750| Using where; Using temporary
 1|SIMPLE     |B    |eq_ref|PRIMARY      |PRIMARY|4      |1  

この接続リークの原因は何ですか?

4

1 に答える 1