1

ここには、2つのスレッドプールを作成するかなり単純なJavaクラスがあります。

  • 実行中のURLストリームに接続し、エントリを1行ずつ読み込み、各エントリをバックエンドのMySQLDBに送信します。

  • それぞれが同じプロセスを実行する複数のスレッドを生成します(以下)。

1.上から最も古いDBエントリを取得します

2.それに応じて解析および処理します

3.いくつかのセクションを別のDBテーブルに保存します

4.実行中のテーブルからこのDBエントリを削除して、分析が完了したことを示します

5.エンドスレッド

2つのプールが必要な理由は、読み取りプロセスが分析よりもはるかに高速であり、エントリを通過するときに各エントリを読み取って分析すると、バックアップが速すぎて着信ストリームが中断するためです。この分離を行うことにより、読み取りは必要な速度で実行でき、分析は、追いつくレコードが安全で追いつくことができることを知っている限り速く進むことができます。

私が抱えている問題は、各並行スレッドが同じ最も古いレコードを取得していることです。個別のスレッドがすべて同時に実行され、それぞれが一意の最も古いDBエントリにアクセスするようにするための最善の方法を知る必要があります。

前もって感謝します。

編集=================================

これまでの返信に感謝します...

私がここで試みていた現在のセットアップをさらに拡張するには、おそらくこのコードセグメントが役立つでしょう...

try
    {
        String strQuery1 = "SELECT lineID,line FROM lineProcessing ORDER BY lineID ASC LIMIT 1;";
        String strQuery2 = "DELETE from lineProcessing WHERE lineID = ?";

        DBConnector dbc = new DBConnector(driver,url,userName,passwd); 
        Connection con = dbc.getConnection();
        con.setAutoCommit(false);
        PreparedStatement pstmt = con.prepareStatement(strQuery1);
        rs = pstmt.executeQuery();
        
        //Now extract the line & Id from the returned result set
        while (rs.next()) {
            lineID = Integer.parseInt(rs.getString(1));
            line = rs.getString(2);
        } //end while 
        
        //Now delete that entry so that it cannot be analysed again...
        pstmt = con.prepareStatement(strQuery2);
        pstmt.setString(1, lineID.toString());
        int res=pstmt.executeUpdate();
        
        con.commit();
        con.setAutoCommit(true);
        con.close();
    }
    catch (SQLException e) {
        System.out.println(">>>EXCEPTION FOUND IN QUERY = " + strQuery1 + " __or__ " + strQuery2);
        e.printStackTrace();
    }

...基本的にDB接続を開き、「Autocommit = false」に設定して、QUERY1を実行し、QUERY2を実行し、両方のトランザクションをコミットして、最終的に接続を閉じます。これは、個々のスレッドが完了するために必要なすべてである必要があります。問題は、分析スレッドプールで実行している各Xスレッドがすべて生成され、このコードのバッチを同時に実行することです(これは予想どおりです)が、設定したDBへの単一の接続アクセスを尊重しませんその上。その後、それらはすべて、分析のために同じ行で戻ります。スレッドが次の反復#2でループするとき、それらはすべて、前の削除に続く分析のためにこの新しい最後の行を返します。

さらに提案がありますか?Javaを介した強制トランザクションSQLの良い例を含めてください。

皆さん、ありがとうございました。

4

2 に答える 2

1

まず、行が特定の時間に「ピックアップ」されたことを示すnull許容日時列を追加します。

次に、処理スレッドで:

  1. トランザクションを開始します
  2. 「ピックアップ」時間がnullの最も古い行を検索します
  3. ピックアップ時間を現在のシステム時間に更新します
  4. トランザクションをコミットします。

分離レベルが少なくともに設定されていることを確認してくださいREAD UNCOMMITTED。2つのスレッドが同じ行を取得しないようにしてください。また、処理スレッドが停止してその行を放棄した場合、ある値よりも前の「ピックアップ」時間の行を定期的にクエリして、ピックアップ時間をnullに設定することでそれらを再処理することでそれを見つけることができます。

または、トランザクションメッセージキューに切り替えるだけで、このほとんどが自動的に行われます。

于 2012-06-25T15:42:11.187 に答える
0

別の解決策は、ワーカースレッドをすべて、行のキーを含むシングルトンで待機させることです。行を書き込み、オブジェクトにキーを配置してから、通知します。「次の」ワーカースレッドがキーを取得して操作します。労働者が待っていることとそうでないことを確認する必要があります。

于 2012-06-25T16:53:20.197 に答える