2

保留中のレコードを取得し、それらを作業単位として「InProcess」状態に更新する処理が必要です。以下のコードが並行性をサポートし、現在のスレッドが処理されるまで他のスレッドが待機することを確認したいと思います。これを達成するための最良の方法は何ですか?

public Collection<Object> processPendingMessages() {
    Collection<Object> messages = null;
    //Retrieve pending messages
    messages = messageDAO.getPendingMessages(Direction.INBOUND);
    //Update pending messages to Inprocess
    if (messages!=null && messages.size()>0) {
        messageDAO.updateMessagesToInprocess(messages); 
    } 
    return messages;
}

ご意見をお待ちしております。ありがとう。

4

3 に答える 3

5

(同期) を使用して、jvm レベルだけで DBAccess 同時実行を処理する必要はありません。あなたの場合、アクセスはデータベースへのアクセスであり、jvm レベルでの単なる同期では不可能です。次のように、データベース接続レベルでも同時実行を処理する必要があります。DBaccess に関する限り、DAO レイヤーにどのような実装があるかについては言及していませんが、それが何であれ、JDBC の次の分離レベルは、実装に関係なく (JDBC、JPA with Hibernate または EJB など)。以下の分離レベルを読み、アプリケーションに適した分離レベルを決定してください。実装をよろしくお願いします。

トランザクション分離レベルは、トランザクションの単位として、トランザクション内のステートメントに表示されるデータを指定します。これらのレベルは、同じターゲット データ ソースに対するトランザクション間で可能な相互作用を定義することにより、同時アクセスのレベルに直接影響します。

データベースの異常

データベースの異常は、単一のトランザクションの範囲から見ると正しくないように見えるが、すべてのトランザクションの範囲から見ると正しい結果が生成されることです。さまざまな種類のデータベース異常について、次のように説明します。

ダーティ リードは次の場合に発生します。 トランザクション A がテーブルに行を挿入します。トランザクション B が新しい行を読み取ります。トランザクション A はロールバックします。トランザクション B は、トランザクション A によって挿入された行に基づいてシステムに対して作業を行った可能性がありますが、その行がデータベースの永続的な部分になることはありません。

反復不能読み取りは、次の場合に発生します。 トランザクション A が行を読み取ります。トランザクション B が行を変更します。トランザクション A は同じ行をもう一度読み取り、新しい結果を取得します。

ファントム読み取りは、次の場合に発生します。 トランザクション A が、SQL クエリの WHERE 句を満たすすべての行を読み取ります。トランザクション B は、WHERE 句を満たす追加の行を挿入します。トランザクション A は WHERE 条件を再評価し、追加の行を取得します。

上記の異常のそれぞれを処理する分離レベル

JDBC_TRANSACTION_NONE これは、JDBC ドライバーがトランザクションをサポートしていないことを示す特別な定数です。

JDBC_TRANSACTION_READ_UNCOMMITTED このレベルでは、トランザクションはデータへのコミットされていない変更を確認できます。このレベルでは、すべてのデータベース異常が発生する可能性があります。

JDBC_TRANSACTION_READ_COMMITTED トランザクション内で行われた変更は、トランザクションがコミットされるまで外部では見えません。これにより、ダーティ リードが可能になるのを防ぎます。

読み取られた JDBC_TRANSACTION_REPEATABLE_READ 行はロックを保持するため、トランザクションが完了していない場合、別のトランザクションはそれらを変更できません。これにより、ダーティ リードと反復不可能なリードが禁止されます。ファントム リードは引き続き可能です。

JDBC_TRANSACTION_SERIALIZABLE テーブルはトランザクションに対してロックされているため、テーブルに値を追加したりテーブルから値を削除したりする他のトランザクションによって WHERE 条件が変更されることはありません。これにより、あらゆる種類のデータベースの異常が防止されます。

setTransactionIsolationメソッドを使用して、接続のトランザクション分離レベルを変更できます

于 2011-05-07T03:04:49.043 に答える
0

データベースに並行性を処理させる必要があります。

DAO で、SQL クエリを発行できます。

// works on oracle.
// query may differ depending on vendor
select * from test where id=? for update 

最初のスレッドはロックを取得できますが、後続のスレッドがクエリを実行するとブロックされます。最初のスレッドがコミット/ロールバックすると、待機中のスレッドの 1 つがブロック解除されます。このようにして、読者に一度に 1 つずつ読んでもらうことができます。

于 2011-05-07T07:20:50.720 に答える
-1

コード内の競合状態を防ぐには、synchronizedキーワードを使用して、前のスレッドがコード ブロックの処理を完了するまで、スレッドがコード ブロックにアクセスできないようにします。

于 2011-05-07T02:20:10.277 に答える