1

データベースを操作する多くのメソッドを持つ DAO クラスがあります。このようなすべてのメソッドに対して 1 つの接続オブジェクトを使用しています (Database.connect() は接続オブジェクトを返します)。

class ExampleDAOImpl implements ExampleDAO{
  private Connection con = null;

  public void method1 () {
   con = Database.connect();
   ....
   con.close();
  }

  public void method2 () {
   con = Database.connect();
   ....
   con.close();
  }

 public void method1 () {
   con = Database.connect();
   ....
   con.close();
  }
}

これは、メソッドごとに新しい接続をインスタンス化して閉じることをお勧めしますか? 各メソッドの最初に接続を初期化し、最後に閉じていますが、「接続を閉じた後は操作は許可されていません」というエラーが発生しています。または、同じ接続オブジェクトを使用して、呼び出したときにそれを閉じる別のメソッドを使用することをお勧めしますか?

4

7 に答える 7

2

クラスのオブジェクトはExampleDAOImplスレッドセーフではありません。そのため、複数のスレッドが同じExampleDAOImplオブジェクトを使用してメソッドを同時に呼び出すと、一方のスレッドが接続を閉じてから、もう一方のスレッドがそれを使用しようとする可能性があります。

可能な解決策:

  • ExampleDAOImplオブジェクトがマルチスレッド コンテキストで使用されないようにしてください。これはまだエラーが発生しやすいです。
  • より良い提案: 単一のConnectionオブジェクトを使用する代わりにConnectionPool、各メソッドの開始時に a を使用して接続を取得し、終了後に解放します。
于 2012-06-18T11:56:59.960 に答える
0

jdbc接続は同時に使用できないため、コードはスレッドセーフではありません。Connection conをThreadLocalに変更し、接続と切断の2つのメソッドを追加してください。

コードは次のようになります。

public class ConnectionHelper
{
private static ThreadLocal<Connection> con = new ThreadLocal<Connection>();

protected Connection getConnection()
{
if(con.get() ==null)
{
con.set(Database.connect());
}
return con.get();
}

protected Connection closeConnection()
{
if(con.get() !=null)
{
con.get().close;
}
}
}

DAOで:public void method1(){try {Connection con = ConnectionHelper.getConnection(); }最後に{ConnectionHelper.closeConnection(); }}

于 2012-06-18T11:55:02.083 に答える
0

BoneCPのような接続プールの実装を使用している場合は、メソッドごとに新しい接続を開いてもまったく問題ありません。メソッドがインスタンス変数ではなく、ローカル変数を参照していることを確認してください。

一方、使用可能な接続プールがなく、1 つの接続のみで作業している場合は、その接続を閉じるのに適した場所を見つける必要があります。これは、プールなしで新しい接続を取得すると非常にコストがかかるためです。

于 2012-06-18T12:00:45.953 に答える
0

2 つの関数を作成する

  connection()

別の

  disconnection()

すべてのメソッドでそれらのメソッドを呼び出す

  function method()
 {
  //call 

  connection();

  //code;

  //call 

     disconnection();
  } 
于 2012-06-18T11:44:38.407 に答える
0

各メソッドで接続を開くときにグローバル接続を作成するポイントは何ですか。これは、method1 から method2 を呼び出すときに発生する可能性があります。method1 によって使用される接続が閉じられます。

一般に、接続の開閉にはコストがかかるため、アプリケーションの使用中に一度接続を作成し、アプリケーションの終了/終了時に接続を閉じることをお勧めします。 .

于 2012-06-18T11:45:50.340 に答える
0

コードを DRY したい場合は、抽象クラスとラムダを使用します

class ExampleDAOImpl implements ExampleDAO{

    // With lambdas
    public void method1 () {
       withConnection( (Connection con) -> {
           // do whatever you want with the connection
           // no need to open or close it
       })
    }

    // Old style abstract class
    public void method2 () {
       withConnection(new TaskExecutor(){
          void doStuff(Connection con){
             // do whatever you want with the connection
             // no need to open or close it
          }
       })
    }

    // This is the magic you have to add.
    private void withConnection(TaskExecutor executer){
        // Instantiate it to avoid race conditions
        // good thing this is the only place
        // you have to worry about opening and closing it
        Connection con = Database.connect();
        executer.doStuff(con);
        con.close();
    }

    private abstract class TaskExecutor{
        abstract void doStuff(Connection con);
    }

}
于 2016-12-16T08:08:36.527 に答える