在我的应用程序中,我必须执行分布式锁定模式。因为我们已经有一个 SQL Server 实例可供使用,所以我们决定在我们的 Web 应用程序的 SQL 层实现锁定是最简单的。
可以根据多种条件获得锁,包括:
- 请求的锁类型
- 任意应用程序标识符
出于所有意图和目的,将上述两个条件视为int
数据类型。
在这种模式中,我们希望将所有的锁视为 FIFO,我相信SERIALIZABLE
隔离级别会给我们。
以下是我们建议执行“锁定”的方式:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
IF EXISTS (SELECT 1 FROM locks WHERE LockType = @LockType AND ApplicationIdentifier = @ApplicationIdentifier)
BEGIN
-- Awesome, the lock will be acquired
INSERT INTO locks OUTPUT INSERTED.LockId VALUES (2,3)
END
ELSE
BEGIN
-- Someone already has the lock
SELECT -1
END
SET TRANSACTION ISOLATION LEVEL READ COMITTED
和“解锁”:
DELETE FROM locks WHERE LockId = @LockId
所以我的问题有两个:
- 我是否也需要进行“解锁”
SERIALIZABLE
? - 还有其他我可以使用的方法/我忘记的任何东西吗?
SQL Server 可以是 2008/2012
尽管名称如此,可序列化的隔离级别并不能保证事务将按顺序执行,或者按接收的顺序执行。相反,可序列化保证事务对数据库具有相同的持久影响,就好像它们以某种未定义的顺序按顺序执行一样(有关更多详细信息,请参见链接)。
是的。SQL Server 已经通过以下方式提供了对任意应用程序锁的支持:
这些内置的应用锁功能提供了广泛的选项,包括自动死锁检测(尽管所需的任何事务回滚都是程序员的责任)。例如,您可以在多种模式下选择事务和会话范围的锁定。使用这些功能来实现您需要的行为应该非常简单,而且肯定比从头开始构建自己的弹性和可靠的锁管理器更简单。