2011-07-01 6 views
1

私は、同じトランザクションデータベースと通信する2台のサーバーがあるとします。トランザクションデータベースを使用してクリティカルセクションを作成するにはどうすればよいですか?

これらの2つのサーバーのうちの1つのみが所定のタイミングのアクション(本質的にはデータベースを使用して同期を実行する)を実行するように設定します。私が聞いたことから、この行に沿った何かがうまくいくかもしれません:

私のテーブルは2列、IDと状態を持っています。コードを次のように設定した場合:

update TABLE set STATUS = 'processing' where ID = 1234 and STATUS != 'processing' 

if (weHaveModifiedAtLeastOneRow) 
{ 
    // do critical section stuff here 
    // This is code that we only want one server to run, not both. 

    update TABLE set STATUS = 'free' where ID = 1234 
} 
else 
{ 
    // We failed to get the lock, so do nothing 
} 

ここではいくつかの概念が欠落していますか?

答えて

1

クリティカルセクションが必要な場合は、dbms_lock.requestを使用します。あなたはこのようなユニーク割り当てる意味のあるロックハンドルトラフを得ることができます:あなたはそれを好む場合

DBMS_LOCK.ALLOCATE_UNIQUE (lockname => 'MYAPP_' || ID, lockhandle => handle); 
success := DBMS_LOCK.REQUEST(lockhandle => handle, timeout => 1); 
if (success = 0) then 
-- Do stuff 
DBMS_LOCK.release(handle); 
else 
-- we waited a second and didn't got the lock. 
end if; 

、あなたはロックの既知の数の上にid値のスペースを投影し、IDの上にハッシュおよびモジュロ演算子を適用することができ、無関係の取引を遅らせる(低い)リスクを受け入れる。

+0

私は私たち自身のロックを巻き込む大きなファンではありません。しかし、これが解決策である可能性があります。しかし、ロックを発行するときに両方の呼び出し側サーバーが同じIDを使用するようにする必要があるため、同期問題を解決するのではなく転送するように見えます。 – APC

関連する問題