我需要检索 SQL Server 2005 生成的标识字段。通常我只会使用 SCOPE_IDENTITY 或向插入中添加一个 OUTPUT CLAUSE,但是在这种情况下这些方法都没有帮助:因为有一个 INSTEAD OF 触发器附加到表。接下来我考虑了@@IDENTITY,但由于表上还有另一个触发器,这也不好。所以我想我必须使用 IDENT_CURRENT。但是,由于这不是 session 安全的,我需要某种方法来确保在我检索到新 ID 之前没有其他 session 可以插入到表中。我已经尝试使用 TABLOCK 和 HOLDLOCK 提示,这似乎有效,但我不是 DBA。所以我的问题是,在 SQL Server 2005 中使用 TABLOCK 和 HOLDLOCK 提示是否会完全阻止插入直到事务结束?
希望这个人为的例子能解释这种情况。 (我意识到,在功能上,在这种情况下,存储过程可以替换两个触发器。)
CREATE TABLE Person
(
PersonID INT IDENTITY PRIMARY KEY,
FirstName VARCHAR(50)
);
GO
CREATE TABLE PersonHistory
(
PersonHistoryID INT IDENTITY(5,1) PRIMARY KEY,
PersonId INT,
FirstName VARCHAR(50)
);
GO
CREATE TRIGGER PersonAudit ON Person
AFTER Insert
AS
INSERT INTO PersonHistory (PersonID, FirstName)
SELECT Inserted.PersonID, Inserted.FirstName
FROM Inserted;
GO
CREATE TRIGGER PersonCleaner ON Person
INSTEAD OF Insert
AS
INSERT INTO Person (FirstName)
SELECT UPPER(Inserted.FirstName)
FROM Inserted;
GO
BEGIN TRAN;
INSERT INTO Person WITH (TABLOCK, HOLDLOCK) (FirstName)
VALUES ('George');
--SELECT @@IDENTITY AS '@@IDENTITY'; -- 5
--SELECT IDENT_CURRENT('Person') AS 'IDENT_CURRENT'; -- 1
--SELECT SCOPE_IDENTITY() AS 'SCOPE_IDENITIY'; -- NULL
DECLARE @PersonID int;
SELECT @PersonID = IDENT_CURRENT('Person');
SELECT @PersonID; -- 1
COMMIT TRAN;
--SELECT * FROM Person;
--SELECT * FROM PersonHistory;
DROP TABLE Person;
DROP TABLE PersonHistory;
最佳答案
您最好的选择是 TABLOCKX 提示,它指定在事务完成之前对表采取排他锁。排他 (X) 锁可防止并发事务访问资源。没有其他事务可以读取或修改由排他 (X) 锁锁定的数据。
关于sql - 在 SQL Server 2005 中使用 TABLOCK 和 HOLDLOCK 提示是否会完全阻止插入直到事务结束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3454242/