【发布时间】:2019-01-14 07:41:58
【问题描述】:
在表 A 上插入后,我有一个表 A (id int, domain nvarchar, status nvarchar) 和一个触发器 A_trigger。触发器调用存储过程,并根据过程的结果更新新插入行的状态.
当我在两个会话中运行它时,我最终遇到了死锁问题:
隔离级别:已提交读
INSERT声明:
INSERT INTO dbo.TEST_TRIGGER (DOMAIN)
VALUES ('toto')
触发器:
CREATE TRIGGER dbo.dim_trigger
ON db.dbo.TEST_TRIGGER
AFTER INSERT
AS
DECLARE @status nvarchar(200),
@domain nvarchar(200),
@trackingId int
BEGIN
SET NOCOUNT ON;
-- This code assumes we insert one and only one row at a time.
SELECT @trackingId = id, @domain = domain FROM INSERTED;
DECLARE @toCallProcName NVARCHAR(200);
SET @toCallProcName = 'db.dbo.'+@domain+'_proc';
EXEC @toCallProcName @status out;
UPDATE db.dbo.TEST_TRIGGER
SET status = @status
WHERE id = @trackingId;
END
我尝试过:
- 使用
WITH (UPDLOCK)发出更新语句,但这不起作用 - 在 (ID) 上创建索引可行,但我担心这个解决方案!!
EDIT1:
表架构:
CREATE TABLE [dbo].[TEST_TRIGGER]
(
[DOMAIN] [NVARCHAR](200) NOT NULL,
[ID] [BIGINT] IDENTITY(1,1) NOT NULL,
[STATUS] [NVARCHAR](100) NULL
)
存储过程:
CREATE PROCEDURE [dbo].[toto_proc]
@res NVARCHAR(200) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
WAITFOR DELAY '00:00:5'
PRINT 'This is me: '+CONVERT(VARCHAR(8), GETDATE(), 108) ;
SET @res = 'OK'
END
有什么帮助吗?
谢谢
【问题讨论】:
-
每行创建一个索引?我认为您不了解索引是什么。
-
请启发我 :) 我不是专业人士
-
向我们展示你实际做了什么 - 每行创建索引,因为我不知道你想做什么。
-
CREATE INDEX i1_TEST_TRIGGER ON dbo.TEST_TRIGGER (id) 也许我应该说“索引的大小会增长得非常快”而不是“..需要为每行创建一个索引”。可能我也很不明白
-
您的触发器有 MAJOR 缺陷,您似乎认为它会被 每行调用一次 - 事实并非如此。触发器将每条语句触发一次,因此如果您的
INSERT导致此触发器触发插入 25 行,您将触发触发器一次和@987654331 @ 伪表将包含 25 行。您的代码将从Inserted中选择这 25 行中的哪一行?它是不确定的,您将获得任意行,而您将忽略所有其他行。您需要重写触发器以考虑到这一点!
标签: sql sql-server database-deadlocks