2009-03-06 11 views
1

2つのバッチプログラムがあります.1つは電子メールを送信し、もう1つはファックスを送信するプログラムです。彼らは両方ともQUEUEという名前のテーブルにアクセスします。SQL Serverでロックする

電子メール送信プログラムでは、これはQUEUEとの関連で発生します。 QUEUEテーブルで

  1. ロックレコード1:QUEUEテーブル内のレコードの削除1
  2. 電子メールのうち、送信
    select 1 from QUEUE with (UPDLOCK) where id = 1
  3. プロセス:基準を満たすQUEUEの各レコードについて
    delete from QUEUE where id = 1
  4. コミットトランザクション(トランザクションは自動コミットではありません)

FAX送信者プログラムでも、手順2でFAXを送信する点を除いて、同様の手順が実行されます。

QUEUEから削除すると、ロックされているという例外がスローされることがあるという問題があります。それにより、電子メール/ファックスの再送信が行われる。私はこれらのプログラムによって処理されたレコード群が交差しないことを確信しています。

削除するレコードは1つだけですが、テーブルの他のレコードに対してUpdate(U)ロックを取得しようとしているようです。他のトランザクションが同じテーブル内の他のレコードをロックしていると、例外が発生します。

これで、「削除」操作で削除するレコード以外のレコードのロックを取得しないようにするオプションがあるかどうかを知る必要があります。なぜなら、この問題は、テーブル内の他のレコードをロックする「削除」操作が原因だと思われるからです。

がちなみに、ここでは(彼らは役立つ場合、私はよく分からない)データベースに関するいくつかの情報です: に

  • リードコミッティスナップショットが
  • スナップショット分離の状態になっています

答えて

2

deleteステートメントでWITH ROWLOCKヒントまたはWITH NOLOCKヒントを使用しようとしましたか?

this articleはありますか?あなたが遭遇した問題を防ぐために(UPDLOCK、READPAST)を使用することをお勧めします。

+0

私は擬似コードに更新ステートメントがありません)削除または選択ステートメントで意味ですか? – rizza

+0

私はselectとXLOCKでXLOCKを使うと、削除のREADPASTがうまくいくかもしれないと思います(テストしました、他のテーブルのロックによってブロックされず、selectステートメントはレコードをロックしようとする他のステートメントに対してレコードをロックします。あなたの提案のためにたくさん。 – rizza

0

ロックは、単一行をロックしてテーブルのセクションをロックしたり、テーブル全体をロックしたりすることをエスカレートします。これは、トランザクションで実際に使用していないレコードをロックする理由です。

トランザクションを使用してレコードをロックする代わりに、ステータスフィールドを使用して処理されたレコードにフラグを立てることができます。

例:

ロック一部のレコード、そして成功したロックされたレコードを取得:

update queue set status = 'email_processing' where status is null and id = 1 
select email, message from queue where status = 'email_processing' 

あなたが明示的に各クエリは、それ自身のトランザクション内で実行されるトランザクションを使用していないので、更新クエリ同じクエリ内の現在のステータスを確認しているので、ステータスを安全に変更できます。送信が完了したら

、レコードを削除:フラグの付いたレコードが単離されるように

delete from queue where status = 'email_processing' 

ファックス送信者はもちろん(「fax_processing」のような)異なるステータスを使用します。

+0

私が心配しているのは、私が削除している時間中にロックエラーが発生した場合です。ロックを削除しても、削除中にロ​​ックエラーが発生する傾向があります(他のレコードがロックされます)。私が考えていることは、その部分に成功するまで削除しようとするコードを作ることです。 – rizza

+0

はい、そうすることができます。しかし、トランザクションがなければ、ロックを経験する可能性はあまりありません。データベースは通常、1つの更新/削除が完了するのを待ってから次の処理を実行します。ほとんどの場合、トランザクションに長時間かかるプロセスやデッドロック状況が発生すると問題になります。 – Guffa

+0

実際には、ロックタイムアウト時間を超えてデッドロックが発生します。それらは私がエラーログで見つけた2つのエラーです。ニックの提案がうまくいくかもしれないと思うが(私はUPDLOCKの代わりにXLOCKを使っているが)、提案に感謝する。 – rizza

関連する問題