sql - 在 SQL Server 2005 中使用 TABLOCK 和 HOLDLOCK 提示是否会完全阻止插入直到事务结束?

标签 sql sql-server-2005 triggers

我需要检索 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/

相关文章:

python - 从pydev导入数据到postgresql

sql - 如何更改自动增长大小? MS SQL Server 2005

sql - 删除前Postgres触发器检查数量

mysql - 触发器-mysql

c# - MySQL 数据库的正确日期时间格式是什么?

sql - 从减去的一个字符串列创建两个字符串列

php - ORDER BY 两个日期mysql查询

sql-server-2008 - SQL Server 兼容级别含义

sql-server-2005 - 这是欧洲+英语语言的最佳排序

sql - 是否可以设置一个触发器,该触发器仅在特定列值更改时触发,并且取决于它调用不同函数的值是什么?