0

ここで1つの基本的な質問があります-私はという名前の新しいデータベースで作業していXpressMPます。

データベースに大量のレコードを挿入するマルチスレッドプログラムを作成しました。データベースに接続しているときに最も重要なことに気づきました。

私のプログラムでは、以下のようなものを使用している場合-

class Task implements Runnable {

   private Connection dbConnection = null;
   private PreparedStatement preparedStatement = null;

   //other stuff

 @Override
  public void run() {

   try {

      dbConnection = getDBConnection();

   } finally {
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
                preparedStatement = null;
            } catch (SQLException e) {
            }
        }
        if (dbConnection != null) {
            try {
                dbConnection.close();
                dbConnection = null;
            } catch (SQLException e) {
            }
        }
    }
  }
}

それは正常に動作し、最後のブロックですべての接続を閉じています。そして、データベースにさらに多くの行を挿入できます。

しかし、複数のスレッドで意図的に静的接続を使用し始めるとすぐに(これは実行すべきではありません)-

class Task implements Runnable {

   private static Connection dbConnection = null;
   private static PreparedStatement preparedStatement = null;

   //other stuff

 @Override
  public void run() {

  try {

    dbConnection = getDBConnection();

   } finally {
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
                preparedStatement = null;
            } catch (SQLException e) {

            }
        }
        if (dbConnection != null) {
            try {
                dbConnection.close();
                dbConnection = null;
            } catch (SQLException e) {
            }
        }
    }
  }
}

データベース全体がハングします。データベースを再起動するまで、そのデータベースを操作できません。つまり、私が持っているJDBCドライバーに問題があるということです。私はこの問題についてDBAに話しました、そして彼らはそのデータベースを所有している人々と話し合っています。

しかし、私の質問は、なぜそれがハングするのかということです。いかなる理由で?

4

2 に答える 2

1

さまざまなスレッド間で1つのオブジェクト参照変数を共有しています...場合によっては、1つの接続オブジェクトが作成され、それが閉じられる(およびその参照がnullに設定される)前に、別のスレッドが開始され、別のオブジェクトが作成され、古いオブジェクトは閉じられません。そのため、その接続はまだ有効であり、ある時点で、開かれる接続が多すぎてDBMSがクラッシュし、「接続が多すぎます」などのエラーが発生する可能性があります。問題はドライブではなく、コードです。一部のスレッドは、別のスレッドによって作成された接続も閉じる可能性があることに注意してください。

catchアウターがないので、スローされている例外は表示されていないと思いますtry。接続を作成しようとすると、例外がスローされます。スタックトレースを表示するために、そこにキャッチを配置してみてください。データベースがこの問題を検出している場合は機能します(機能する可能性があります)。

于 2013-02-08T03:17:48.220 に答える
1

JDBCはスレッドセーフではないため、静的フィールドに格納されているかどうかに関係なく、複数のスレッドから1つのConnectionオブジェクトを並行して使用しないでください。これを行うと、1つのスレッドが他のスレッドのクエリの途中でクエリを送信する可能性があるため、データベースは完全なガベージを受け取ります。データベースが堅固でない場合、このガベージはデータベースを破壊する可能性があります。

于 2013-02-08T04:42:43.077 に答える