2017-11-20 17 views
0

こんにちはすべて

でプールに解放されていません。私はその日の良いところでこの問題に座っていました。だからあなたのうちの一人が私を助けてくれることを願っています。接続は私の接続が解放されていない何らかの理由でマルチスレッドプログラム

DataSourceは、Swagger jaxwsサーバーにあります。だから私はプールから接続を取得している各要求に。これは、プールから接続を返す私のDataSourceクラスです:データベース接続を呼び出すことによって、それを取り出すの使用を必要とする各機能については

import java.beans.PropertyVetoException; 
import java.io.IOException; 
import java.sql.Connection; 
import java.sql.SQLException; 
import org.apache.commons.dbcp2.BasicDataSource; 
/** 
* 
* @author Lagoni 
*/ 
public class DataSource { 
    private static DataSource datasource; 
    private BasicDataSource ds; 
    private DataSource() throws IOException, SQLException, PropertyVetoException { 
     ds = new BasicDataSource(); 
     ds.setDriverClassName("org.postgresql.Driver"); 
     ds.setUsername("username"); 
     ds.setPassword("pw"); 
     ds.setUrl("jdbc:postgresql://host" + 5432 + "/db"); 

     ds.setMaxWaitMillis(20000); //wait 10 seconds to get new connection 
     ds.setMaxTotal(5); 
     ds.setMaxIdle(5); 
     ds.setTestWhileIdle(true); 
     ds.setTestOnReturn(true); 
     ds.setTimeBetweenEvictionRunsMillis(1000); 
     ds.setSoftMinEvictableIdleTimeMillis(100); 
     ds.setMinEvictableIdleTimeMillis(10); 
     ds.setMaxConnLifetimeMillis(1000*60*10); 
    } 

    public static DataSource getInstance() throws IOException, SQLException, PropertyVetoException { 
     if (datasource == null) { 
      datasource = new DataSource(); 
     } 
     return datasource; 
    } 

    public Connection getConnection() throws SQLException { 
     return ds.getConnection(); 
    } 

} 

Connection con = DataSource.getInstance().getConnection(); 

私は取得しています場所です "接続を取得できません、プールエラーです。アイドル状態のオブジェクトを待機するタイムアウトです。 "スレッドごとに1つの接続しか使用されていないことを確認しています。したがって、関数がデータベースへの複数の呼び出しを行う必要がある場合、関数con変数が再利用されます。

私はcon.close()を呼び出すべきではないという結論に達しました。なぜなら、プールへのヌル接続が返されるからです。関数は、接続を完了すると、次のと呼ばれている:私は、接続がアイドルと宣言される前に行うことを忘れてい何かが

resultSet.close(); 
statement.close(); 

ありますか?それとも、私は接続プールを正しく実装していないのですか?別の種類のプールを使用してみるべきですか?

私は、次のMavenの依存関係を使用しています:

<dependency> 
    <groupId>org.apache.commons</groupId> 
    <artifactId>commons-dbcp2</artifactId> 
    <version>2.1.1</version> 
</dependency> 
<dependency> 
    <groupId>org.apache.commons</groupId> 
    <artifactId>commons-pool2</artifactId> 
    <version>2.4.3</version> 
</dependency> 
<dependency> 
    <groupId>org.postgresql</groupId> 
    <artifactId>postgresql</artifactId> 
    <version>42.1.4</version> 
</dependency> 

編集1

これが解決策になるだろうか?

try(Connection con = DataSource.getInstance().getConnection()){ 
     UploadedFile file = new FileServerImplementation().uploadFile(fileType, fileName, folderId, projectId, tokenString, fileInputStream, con); 
     if(file != null){ 
      return Response.ok().entity(file).build(); 
     } 
    } 

ここuploadFile方法は以下の通りです:

public UploadedFile uploadFile(String fileType, String fileName, Long folderId, Long projectId, String tokenString, InputStream fileInputStream, Connection con) throws SQLException, IOException, PropertyVetoException{ 
    IOController ioController = new IOController(); 
    DatabaseController controller = DatabaseController.getInstance(); 
    UploadedFile file = null; 
    if(ioController.uploadFile(fileType, fileName, controller.getFolderPath(folderId, con), projectId, fileInputStream)){ 
     file = controller.uploadFile(fileType, fileName, folderId, projectId, con); 
    }else{ 
     System.out.println("Error uploading " + fileName + " to folder!"); 
    } 
    return file; 
} 

IOControllerがディスク上にファイルを保存し、その後メソッドuploadFileがデータベースにいくつかのデータをアップロードします。または、私がDatabaseControllerクラスのメソッドを呼び出すたびに、プールから新しい接続を取得する必要がありますか?

ソリューション

私はアプローチとして編集1を使用して終了。私はちょうど私がそれらをもう一度閉じることなく不必要な接続を作成していないことを確認しなければならなかった。

+1

あなたはcon.close()がnullを返すと述べましたが、この結論にどうやって来ましたか?ほとんどの接続プールの実装では、接続をプールに適切に解放するためにcon.close()を呼び出すプログラマが依存しています。 – jon5477

+0

あなたは間違った結論に達しました。 – Kayaman

+0

最後にcon.closeをもう一度使ってみます。しかし、私はそれを試して初めて仕事をしなかった。 – Lagoni

答えて

2

接続プールを使用する場合は、接続をcloseにしてプールに戻して再利用する必要があります。 ではないスレッドで接続を保持します。

+0

私は以前に接続を閉じようとしましたが、別の設定であったかもしれませんが、接続を閉じたままにしていました。私は明日もう一度お試しになり、それが動作するかどうかをお知らせします。 – Lagoni

+0

@Lagoniあなたはまた毎回新しい接続を取得するshoul。それを保持しないでください。 – OldCurmudgeon

+0

1を編集しますか?解決策はありますか? – Lagoni

関連する問題