我有大约 20 个存储过程,它们相互消耗,形成树状依赖链。
然而,存储过程使用内存中的表进行缓存,并且可以从许多不同的客户端同时调用。
为了防止对内存表的并发更新/删除尝试,我使用 sp_getapplock 和SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT ON;
.
我正在使用每个存储过程唯一的存储过程参数的散列,但是对具有相同参数的相同存储过程的多个并发调用应该生成相同的散列。正是这种对具有相同参数的相同存储过程的并发调用的哈希相等性为我提供了一个有用的资源名称来获取我们的应用锁。
下面是一个例子:
BEGIN TRANSACTION
EXEC @LOCK_STATUS = sp_getapplock @Resource= [SOME_HASH_OF_PARAMETERS_TO_THE_SP], @LockMode = 'Exclusive';
...some stored proc code...
IF FAILURE
BEGIN
ROLLBACK;
THROW [SOME_ERROR_NUMBER]
END
...some stored proc code...
COMMIT TRANSACTION
尽管将所有内容包装在应该阻止任何并发更新或删除的 applock 中,但我仍然收到错误 41302:
当前事务试图更新自该事务开始以来已更新的记录。交易被中止。在批处理结束时检测到不可提交的事务。事务被回滚。
我是否错误地使用了 sp_getapplock?看来我建议的方法应该有效。