2011-01-15 9 views
0

私は休止状態とトランザクションを初めて使います。休止トランザクション(1行をinprogとして読み込み、他のテーブルに書き込む)(他のテーブルを読み込み、notinprogに行を設定)

テーブル内に進行中の状態としてマークする行があります。私は2番目のテーブルを持っています。これは、進行中のワーカーが受け取った行をラップアップする直前に受け取る行を記述するためのものです。

は、これら2つのテーブルを使用している2つのトランザクションがある:

1)トランザクションが最大シーケンス番号列の進行中のダミー行をフェッチします。この行を見るとき、その行がコミットされたことを知る必要があります。 (最小の分離は何ですか?)次に、行の進行中フラグが真であるかどうかを確認します。進行中の場合、進行中の行をすでにコミットしている別の長期実行スレッド(単一のトランザクションではない)があり、新しいデータを補助テーブルに追加して、実行中のスレッドは、補助テーブルから行を取得/削除/処理し、それらを使用して何かを行い、最終的には、単一のアトミックなトランザクションでinprogressをfalseに設定します。

2)2番目のスレッドが起動し、開始時に進行中がtrueにコミットされていることがわかります。別々のトランザクションでいくつかの作業を行います。 (1)スレッド1のいくつかが書いた補助データを第2のテーブルに読み込み、(2)それらを除去して処理し、(3)インスレッドの進行中の列を書き込み、進捗行をfalseにします。

最初の質問は、これらの2つの関連トランザクションの場合、スレッド2が終了するとスレッド1が2番目のテーブルBに追加したすべての補足データを処理したということで、それは進行中の状態を見たとき。

また、スレッド2で進行中の状態をfalseに設定するために休止状態のセッターを使用する場合、補助データを取り出し、削除して処理する前にそれを実行する必要があることに非常に懸念しています。そして、トランザクションで最初にやってみると、孤立を引き起こすために休止状態になるためにセッションをフラッシュする必要がありますか?

おかげで、 アンディ

答えて

0

キーがJava用語でそれに同期すると本質的に同等あなたの進行中のフラグを保持している行をロックすることであると私には思えます。他のデータを読み取る前に(または同時に)これを一貫して行う必要があります。読み取りコミットされた分離レベルの使用は問題ありません。

LockMode.UPGRADE(またはLockOptions.UPGRADEと変更されていると思います)を使用して行をロックするには、クエリまたはセッションから行を取得するときに休止状態にすることができます。ネイティブSQLクエリを使用している場合は、データベースの実装(通常は... FOR UPDATE)を使用する必要があります。例えば:

Hibernateは SELECT s_.id, ... FROM status_data s_ WHERE s_id = ? FOR UPDATE OF s_たり、方言のための適切な同等のものを生成するために使用します
StatusData status = (StatusData) session.get(StatusData.class, id, LockOptions.UPGRADE); 

(例えばwith(updlock,rowlock)

ISTRあなたもクエリでこれを指定したので、おそらくのようなもの:

StatusData status = (StatusData) 
    session.getNamedQuery("Status.FindLatest") 
     .setLockMode("status", LockMode.UPGRADE) 
     .uniqueResult(); 

この行をこのモードに設定すると、トランザクションを完了するまで同じクエリを実行しようとしている他のコードがブロックされ、ステータスまたはその従属コレクションを自由に変更できます。

私はあなたがHibernateでトランザクションを使用することのドキュメントを見つけたと思いますか? http://docs.jboss.org/hibernate/core/3.3/reference/en/html/transactions.html

私は宣言的なトランザクション境界を使って良い経験がありました。だから、DAO/EJB /データベースインタラクションを実行するもの、インタフェースを介して公開されたもの、そしてデコレータは、そのインタフェースを通してすべての呼び出しを自動的に開始/コミット/ロールバックします。 SpringとJ2EEのコンテナは、このようなことをするためのインフラストラクチャを提供しますが、手で行うことも簡単です。これにより、どのビットがデータベーストランザクション内にあり、どのビットがそうでないのかがコード内で明確になります。あなたは相当やるのであれば:finishProcessing()のあなたの基本的な実装では

void finishProcessing() { 
    Session session = sessionFactory.openSession(); 
    Transaction tx = session.beginTransaction(); 
    ThreadLocalSessionContext.bind(session); 
    boolean committed = false; 
    try { 
     underlying.finishProcessing(); 
     tx.commit(); 
     committed = true; 
    } finally { 
     if (!committed) tx.rollback(); 
     session.close(); 
     ThreadLocalSessionContext.unbind(sessionFactory); 
    } 
} 

を単にあなたの他の変更を行うと戻り、ステータス行を取得することができます:トランザクションがコミットされます(暗黙的にセッションをフラッシュする)と、セッションは途中で終了しました。

関連する問題