10 ~ 15 個のテーブルへの変更を 1 回のトランザクションとしてコミットするアプリケーションからの複雑な作業単位があります。作業単位は、スナップショット分離で実行されます。
一部のテーブルには、ストアド プロシージャを実行してメッセージをキューに記録するトリガーがあります。メッセージには、テーブル名、キー、および変更タイプが含まれています。これは、SQL2005 との下位互換性を確保するために必要です。組み込みのキューイングを使用できません。
問題は、ストアド プロシージャを書き込むキューでブロックとタイムアウトが発生することです。次のようなメッセージが表示されます。
Snapshot isolation transaction aborted due to update conflict. You cannot use snapshot isolation to access table 'dbo.tblObjectChanges' directly or indirectly in database
または、そのテーブルへの書き込みでタイムアウトが発生します。
トリガー内から、メッセージ キューの書き込みを行うストアド プロシージャへの (またはその中の) 特定の呼び出しのトランザクション分離を変更する方法はありますか? 最後の手段として、非同期で実行されるストアド プロシージャの削除部分または更新部分の呼び出しを行うことはできますか?
ストアド プロシージャの SQL は次のとおりです。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_NotifyObjectChanges]
@ObjectType varchar(20),
@ObjectKey int,
@Level int,
@InstanceGUID varchar(50),
@ChangeType int = 2
AS
SET NOCOUNT ON
DECLARE @ObjectChangeID int
--Clean up any messages older than 10 minutes
DELETE from tblObjectChanges Where CreatedTime < DATEADD(MINUTE, -10, GetDate())
--If the object is already in the queue, change the time and instanceID
SELECT @ObjectChangeID = [ObjectChangeID] FROM tblObjectChanges WHERE [ObjectType] = @ObjectType AND [ObjectKey] = @ObjectKey AND [Level] = @Level
IF NOT @ObjectChangeID is NULL
BEGIN
UPDATE [dbo].[tblObjectChanges] SET
[CreatedTime] = GETDATE(), InstanceGUID = @InstanceGUID
WHERE
[ObjectChangeID] = @ObjectChangeID
END
ELSE
BEGIN
INSERT INTO [dbo].[tblObjectChanges] (
[CreatedTime],
[ObjectType],
[ObjectKey],
[Level],
ChangeType,
InstanceGUID
) VALUES (
GETDATE(),
@ObjectType,
@ObjectKey,
@Level,
@ChangeType,
@InstanceGUID
)
END
tblObjectChanges の定義:
CREATE TABLE [dbo].[tblObjectChanges](
[CreatedTime] [datetime] NOT NULL,
[ObjectType] [varchar](20) NOT NULL,
[ObjectKey] [int] NOT NULL,
[Rowversion] [timestamp] NOT NULL,
[Level] [int] NOT NULL,
[ObjectChangeID] [int] IDENTITY(1,1) NOT NULL,
[InstanceGUID] [varchar](50) NULL,
[ChangeType] [int] NOT NULL,
CONSTRAINT [PK_tblObjectChanges] PRIMARY KEY CLUSTERED
(
[ObjectChangeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
GO