我有一个表,它有一个“LockedBy”字段,它可以是空的(没有人锁定这条记录进行编辑),也可以有一个用户 ID。
这个想法是让只有一个团队成员可以一次“检查”记录(以及与该记录相关的其他表中的所有记录),这在我的脑海中听起来很容易,直到我意识到我真的不知道锁定如何处理 SQL Server 中的事务。
目前,我正在使用事务更新表并在存储过程中保存点,但我不知道如何合并“锁”:
BEGIN TRANSACTION TR1
BEGIN TRY
UPDATE LOCK_TABLE SET UpdatedDate=GETDATE() WHERE ID=@ID
--======================================================================
--only update this table if the lock field is null; make sure no one
--else can modify the lock field until the whole of TR1 is committed
--or rolled back
--======================================================================
--Table 1
SAVE TRANSACTION TR2
BEGIN TRY
UPDATE TABLE1 SET somefield='something' WHERE LockTableID=@ID
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION TR2;
PRINT ERROR_MESSAGE();
END CATCH
COMMIT TRANSACTION TR1;
--======================================================================
--release the lock
--======================================================================
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION TR1;
SET @RETURN=-1;
PRINT ERROR_MESSAGE();
END CATCH
我从并发编程的角度理解锁,但是每个 SQL Server 对锁的介绍似乎要么是关于防止死锁,要么是关于如何使用不同粒度的锁。
我想我想要的只是“从这里到这里,不要让其他人执行这个存储过程”(就像多线程函数中的锁),但也许我是从错误的角度来的。
当我使用事务时,SQL Server 会自动执行我想要的操作吗?或者我需要添加一些特殊的东西,以便我可以锁定对该存储过程的其他调用?
SQL Server 具有非常广泛的锁定选项。大多数是自动的,但如果需要,您可以在特定情况下强制使用它们。您还可以在各个级别上实现非默认锁定行为。您正在寻找的内容(据我所知)最好由名为 rowlock 的表提示来处理。根据您的隔离级别,您可能需要额外的提示来确保其功能。您可以在以下链接中了解更多信息:https ://msdn.microsoft.com/en-us/library/ms187373.aspx
迂回的想法,改为使用权限。
也许您使用的存储过程会根据签入或签出记录添加或删除其他人的权限。