我需要检索 SQL Server 2005 生成的标识字段。通常我只使用 SCOPE_IDENTITY 或向插入添加 OUTPUT CLAUSE,但是这些方法在这种情况下都没有帮助:因为表附加了 INSTEAD OF 触发器。接下来我考虑了@@IDENTITY,但由于表上还附加了另一个触发器,这也不好。所以我想我必须使用IDENT_CURRENT。然而,由于这不是会话安全的,我需要某种方法来确保在我检索到新 ID 之前没有其他会话可以插入表中。我尝试过使用 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) 锁锁定的数据。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)