2

DB.DATA_FEEDT/SQL プロシージャを使用して更新するテーブルがあります。毎分、以下の手順が異なるデータに対して 100 回実行されます。

ALTER PROCEDURE [DB].[UPDATE_DATA_FEED]  
   @P_MARKET_DATE varchar(max),
   @P_CURR1 int,
   @P_CURR2 int,
   @P_PERIOD float(53),
   @P_MID float(53)
AS 

   BEGIN

      BEGIN TRY

         UPDATE DB.DATA_FEED
            SET 
               MID = @P_MID, 
               MARKET_DATE = convert(datetime,@P_MARKET_DATE, 103)
            WHERE 
               cast(MARKET_DATE as date) = 
               cast(convert(datetime,@P_MARKET_DATE, 103) as date) AND 
            CURR1 = @P_CURR1 AND 
            CURR2 = @P_CURR2 AND 
            PERIOD = @P_PERIOD

         IF @@TRANCOUNT > 0
            COMMIT WORK 

      END TRY

      BEGIN CATCH

         --error code

      END CATCH

   END

 END

ユーザーがアプリケーションを使用する場合、以下の SQL に従って、このテーブルからも読み取ります。この選択は、1 分間に何千回も実行される可能性があります。(疑問符はパーサーによって適切な日付/数字に置き換えられます)

DECLARE @MYDATE AS DATE;
SET @MYDATE='?'
SELECT *
FROM DB.DATA_FEED
WHERE MARKET_DATE>=@MYDATE AND MARKET_DATE<DATEADD(D,1,@MYDATE)
AND CURR1 = ?
AND CURR2 = ?
AND PERIOD = ?

ORDER BY PERIOD

めったにありませんが、データベースがロックされることがあります。

http://sqlserverplanet.com/troubleshooting/blocking-processes-lead-blockerのスクリプトを使用すると、SPID=58 であることがわかりました。次に、DECLARE @SPID INT; を実行しました。@SPID = 58; を設定します。DBCC INPUTBUFFER(@SPID) を実行して、select ステートメントであることが判明した SQL スクリプトを見つけます。

SQL コードに何か問題がありますか? 今後このようなロックが発生しないようにするにはどうすればよいですか?

ありがとう

4

1 に答える 1

0

読み手は書き手よりも優先されるため、誰かが書いているとき、読み手は書き終わるのを待たなければなりません。試すことができるテーブル ヒントは 2 つあります。1 つはコミットされていない行を読み取る NOLOCK (ダーティ リード) で、もう 1 つは READPAST (最後のコミットでコミットされた情報のみを読み取る) です。どちらの場合も、リーダーがテーブルをブロックすることはありません。ライターがデッドロックしないためです。

ライターは他のライターをブロックできますが、私の理解が正しければ、実行ごとに 1 つの書き込みしかできないため、リーダーは書き込みをインターカレートし、デッドロックを減らします。

それが役に立てば幸い。

于 2014-08-01T13:39:24.530 に答える