擅长:python、mysql、java
<p>您不希望多个会话为同一键值运行第一个SELECT。这就是导致僵局的原因。在</p>
<p>正确的模式是:</p>
<pre><code>BEGIN TRAN
IF EXISTS (SELECT BlahID FROM MyTable WITH (UPDLOCK,HOLDLOCK) WHERE BlahID = ?)
BEGIN
UPDATE MyTable SET
Foo = ?,
Bar = 1
WHERE BlahID = ?
END
ELSE
BEGIN
INSERT INTO MyTable (Foo, Bar)
VALUES (1, ?,)
END
COMMIT TRAN
</code></pre>
<p>如果行存在,SELECT将锁定该行;如果该行不存在,则将对键范围获取更新范围锁。在这两种情况下,第二个会话将阻塞存在性检查,直到第一个会话完成插入或更新。在</p>
<p>如果不使用锁提示进行读取(无论是在SELECT、UPDATE、INSERT或MERGE中),那么如果该行不存在,则不会获取锁,并且多个会话可能会尝试插入。在</p>