0

SQLサーバーがデッドロックメッセージを返す原因となっているセットアップを改善するための提案を取得したいと思います。TaskParallelライブラリを実際に使用する複数のスレッドアプリケーションがあり、各タスクはストアドプロシージャを使用して、テーブルからIDを選択し、その処理に使用します。同じステートメントのテーブルからそのIDをすぐに削除しますが、それがデッドロックの原因であると思います。このテーブルは、インデックスのない一意のIDの1つの列で構成されています。定期的にバッチ削除を行うことを考えましたが、それは複数のサーバー間で使用されたIDの集計を維持することを意味します。

これが私のsqlストアドプロシージャです:

   CREATE PROCEDURE [dbo].[get_Ids]
   @id nvarchar(20) OUTPUT

    AS

    BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
   SET NOCOUNT ON;

       Select top 1 @id = siteid from siteids 
       delete siteids where siteid = @id



   END

これを行うためのより良い方法はありますか?私のプロセスは非常に高速に動作し、以前はWebリクエストサービスからこのIDをリクエストしていましたが、これには3秒かかりました。

4

1 に答える 1

1

試してみることがいくつかあります。たぶん、選択したばかりのレコードを削除することをDBに示唆してみてください。こうすることで、ロックを早期に取得できます。これを機能させるには、プロシージャ全体をトランザクションでラップしてから、選択をヒントにする必要があります。次のようになります。

BEGIN TRANSACTION  
  SELECT TOP 1 @id = siteid from siteids WITH (UPDLOCK, HOLDLOCK)
  DELETE siteids WHERE siteid = @id
COMMIT TRANSACTION

また、siteid列にインデックスが付けられていることを確認してください(または、一意であると言うので、主キーとしてタグ付けしてください)。そうしないと、テーブルをスキャンしてレコードを削除する必要があり、時間がかかるため、デッドロックが悪化する可能性があります。削除します。

一般的なデッドロックの場合は、SQLプロファイラーを実行して、デッドロックグラフがどのように表示されるかを確認します。何か別のことが起こっている可能性があります。

于 2012-11-03T04:46:21.663 に答える