2012-03-20 8 views
1

SpringアプリケーションでJDBCTemplateで接続をプールするためにBasicDataSourceを使用しようとしています。私が読んだことから、これは本当にシンプルなはずです:XMLでBasicDataSourceを設定し、データソースをBeanに注入し、セッターメソッドで新しいJDBCTemplateを作成するだけです。JDBCTemplateでBasicDataSourceが接続をプールしない

私がこれをしたとき、私のパフォーマンスはひどいことに気付きました。だから、私はSpringのSingleConnectionDataSourceに切り替えました。何が起こるかを知るために、私のパフォーマンスはと多くてになっています。プロファイラツールを使って調査を始めました.BaseDataSourceを使用すると、すべてのクエリに対して新しい接続が作成されていたことに気付きました。

さらに調査すると、クエリの終了後に接続が閉じられている場所がわかります。具体的にSpringのDataSourceUtilクラスで:

public static void doReleaseConnection(Connection con, DataSource dataSource) throws SQLException { 
    if (con == null) { 
     return; 
    } 

    if (dataSource != null) { 
     ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); 
     if (conHolder != null && connectionEquals(conHolder, con)) { 
      // It's the transactional Connection: Don't close it. 
      conHolder.released(); 
      return; 
     } 
    } 

    // Leave the Connection open only if the DataSource is our 
    // special SmartDataSoruce and it wants the Connection left open. 
    if (!(dataSource instanceof SmartDataSource) || ((SmartDataSource) dataSource).shouldClose(con)) { 
     logger.debug("Returning JDBC Connection to DataSource"); 
     con.close(); 
    } 
} 

私が気づく事は、接続を開いたままに「SmartDataSource」のいくつかの特別なロジックがあります。これは、私が見ていた動作を部分的に説明しています.SingleDataSourceはSmartDataSourceを実装しているため、接続は閉じられません。しかし、私はBasicDataSourceを使用することで接続のclose()メソッドがプールへの接続を返すと考えました。しかし、プロファイラで何が起きているのかを見ると、closeメソッドは実際には私のsybase接続で呼び出されています。私が見たいと思うような「Pooled Connection Wrapper」はありません。

最後にもう1つ(これは私が今調べていることです):いくつかの私のクエリ(データベースへのコミットを含む)にはTransactionTemplateを使用しますが、単純なクエリはtransactionTemplate内にありません。それが問題と関係しているかどうかわかりません。

EDIT 1:

OK]をクリックして最終的にここに、オフプロジェクトビットを引っ張り、取得後に調査するいくつかのより多くの時間がここ

public class DBConnectionPoolTest { 

@Autowired 
@Qualifier("myDataSource") 
private DataSource dataSource; 

@Test 
public void test() throws Exception{ 
    JdbcTemplate template = new JdbcTemplate(dataSource); 
    StopWatch sw = new StopWatch(); 
    sw.start(); 
    for(int i=0; i<1000; i++){ 
     template.queryForInt("select count(*) from mytable"); 
    } 
    sw.stop(); 

    System.out.println("TIME: " + sw.getTotalTimeSeconds() + " seconds"); 
}} 

は私の2つです、問題を示して非常に簡単なテストでしまいましたデータソースの設定:

<bean id="myDataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource"> 
    <property name="driverClassName" value="${db.driver}" /> 
    <property name="url" value="${db.url}" /> 
    <property name="username" value="${db.username}" /> 
    <property name="password" value="${db.password}" /> 
</bean> 

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
    <property name="driverClassName" value="${db.driver}" /> 
    <property name="url" value="${db.url}" /> 
    <property name="username" value="${db.username}" /> 
    <property name="password" value="${db.password}" /> 
</bean> 

最初の設定でテストを実行すると、約2.1秒かかります。 2番目の設定で実行すると、約4.5秒かかります。私は、maxActive = 1とtestOnBorrow = falseを設定するなど、BasicDataSourceでさまざまなパラメータを試しましたが、何も違いはありません。

+0

configを表示して、データソースとJdbcTemplateを設定して注入する場所を示します。 – skaffman

答えて

0

私の場合の問題は、sybase用のjdbcライブラリが古くなったことだと思います。