我需要检索由SQL Server 2005生成的标识字段.通常我只使用SCOPE_IDENTITY或向插入添加OUTPUT CLAUSE,但是在这种情况下这些方法都没有帮助:因为有一个附加到表的INSTEAD OF触发器.接下来我考虑了@@ IDENTITY,但是因为表中还附加了另一个触发器,所以这也不好.所以我想我必须使用IDENT_CURRENT.但是,由于这不是会话安全,我需要一些方法来确保在检索到新ID之前没有其他会话可以插入到表中.我已尝试使用TABLOCK和HOLDLOCK提示,这似乎有效,但我不是DBA.所以我的问题是,将使用SQL Server 2005中的TABLOCK和HOLDLOCK提示COMPLETELY阻止插入直到事务结束?
希望这个人为的例子能够解释这种情况. (我意识到,在功能上,存储过程可以在这种情况下替换两个触发器.)
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)锁定锁定的数据.