【问题标题】:Azure SQL DB - Handling and identifying concurrent transactionsAzure SQL DB - 处理和识别并发事务
【发布时间】:2021-09-04 00:53:57
【问题描述】:

我使用 Azure SQL DB(单 DB、基本、DTU、预配置)。隔离级别默认为 is_read_committed_snapshot_on = 1。

要求是锁定表中的记录,如果它即将被更新。锁定期间...

#1。应该允许其他用户读取整个表(包括正在更新的行)。

#2。应该允许其他用户更新其他记录(正在更新的记录除外)。

#3。应该允许其他用户识别谁锁定了该行(即,一个查询来识别锁,传递表名和记录的PK。)

对于 #1,提示 SELECTUPDLOCK 可以完成这项工作。

对于#2,我尝试了UPDLOCKROWLOCKREADPAST 的不同组合。所有人都在IX 模式下锁定整个表(对象),在U 模式下锁定RID。因此,它会阻止其他用户更新表中的其他记录。如何允许其他用户(会话)更新表的其他行?

对于#3,传递表名/SPID,并使用DMV dm_tran_locksdm_exec_sessions,我们可以确定该表已被该用户锁定。在行级别(使用 PK)之前,查询如何才能正常? (即如果两个用户锁定了两个不同的行,我们如何识别用户 A 锁定了第 1 行,而用户 B 锁定了第 2 行?)有可能吗?

非常感谢您的帮助!

提前致谢!

【问题讨论】:

    标签: sql-server locking isolation-level


    【解决方案1】:

    IX 模式下的(对象)和 U 模式下的 RID

    表级 IX 和 RID U 锁不会阻止其他会话更新其他行。仔细检查您的索引,尤其是考虑添加聚集索引而不是使用堆表。

    查询如何直到行级别(使用PK)?

    没有很好的方法来做到这一点。 sys.dm_trans_locks.resource_description 将匹配锁定行的 %%lockres%% 未记录的虚拟列。但是其他会话无法读取锁定的行,您必须扫描整个表以查找匹配项。如果你真的需要这个,你可以引入一个额外的表,你可以在其中为拥有锁的会话插入 (ID,session_id)。

    【讨论】:

    • 感谢您的投入,布朗。不是引入新表,而是在表中添加了几个新列(LOCKED_BY 和 LOCKED_AT)。通过更新新列而不是获取物理锁来以编程方式处理锁。似乎更容易,虽然它需要额外的代码更改。
    • 这是一个很好的模式,并且可能允许您在编写 LOCKED_BY 和 LOCKED_AT 之后提交 SQL Server 事务。
    猜你喜欢
    • 1970-01-01
    • 2022-10-08
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 2019-01-14
    相关资源
    最近更新 更多