我需要检索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;
答案 0 :(得分:2)
您最好的选择是TABLOCKX提示,它指定在事务完成之前对表进行独占锁定。独占(X)锁防止并发事务访问资源。没有其他事务可以读取或修改使用独占(X)锁定锁定的数据。