在.NET 6应用程序中,EntityFramework用于跟踪实体和更新相关字段。为了改进大容量更新,添加了EfCore.BulkExtensions包。
在.BulkUpdate期间,生成并执行一个SQL语句(由所描述的包)。我注意到了WITH (HOLDLOCK)部分。我已经阅读了一些关于提示和可能的竞争条件的文档,但是它们是否发生在只使用UPDATE命令的合并中?简而言之,如果MERGE语句只包含一个UPDATE命令,或者可以安全地删除它,这是否需要(HOLDLOCK)提示?
示例查询:
MERGE TargetProducts WITH (HOLDLOCK) AS Target
USING SourceProducts AS Source
ON Source.ProductID = Target.ProductID
WHEN MATCHED THEN UPDATE SET
Target.ProductName = Source.ProductName,
Target.Price = Source.Price;发布于 2022-09-28 10:08:18
HOLDLOCK提示将SERIALIZABLE隔离语义应用于暗示的表。例如,在执行“upsert”(如果存在更新,则插入其他内容)或仅在当前不存在具有相同键的行时插入行时,这是必要的。
在这两种情况下,问题都是MERGE测试,以查看某个特定行是否不存在,并且该条件在插入完成之前仍然有效。
如果没有可序列化的语义,就没有需要锁定的行来提供必要的保证。Range键锁定通过锁定将添加的任何新行的键范围来提供Server中的解决方案。
这不是MERGE的“bug”。单独的INSERT和UPDATE语句受到相同的基本考虑,还需要隔离级别提示,以确保在高度并发情况下的正确行为。
如果HOLDLOCK在一个或多个现有行上操作,则不需要使用MERGE提示,就像您的更新一样。
顺便提一句,HOLDLOCK是这个提示的糟糕名称,只为向后兼容性而维护。我希望实体框架团队使用更现代的SERIALIZABLE同义词。
相关问答:服务器2014并发输入问题
https://dba.stackexchange.com/questions/317495
复制相似问题