3 回答

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超4個(gè)贊
在測(cè)試行是否存在時(shí)傳遞updlock,rowlock,holdlock提示。Holdlock確保所有插件都已序列化;行鎖允許并發(fā)更新現(xiàn)有行。
如果您的PK是bigint,則更新可能仍會(huì)阻止,因?yàn)閮?nèi)部哈希會(huì)退化為64位值。
begin tran -- default read committed isolation level is fine
if not exists (select * from <table> with (updlock, rowlock, holdlock) where <PK = ...>
-- insert
else
-- update
commit

TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超3個(gè)贊
編輯:Remus是正確的,條件插入w / where子句不能保證相關(guān)子查詢和表插入之間的狀態(tài)一致。
正確的表提示可能會(huì)強(qiáng)制保持一致狀態(tài)。INSERT <table> WITH (TABLOCKX, HOLDLOCK)似乎有效,但是我不知道這是否是有條件插入的最佳鎖定級(jí)別。
在像Remus所述的瑣碎測(cè)試中,TABLOCKX, HOLDLOCK顯示的插入量是沒有表提示的插入量的5倍,并且沒有PK錯(cuò)誤或過程。
原始答案,不正確:
這是原子的嗎?
是的,條件插入w / where子句是原子的,您的INSERT ... WHERE NOT EXISTS() ... UPDATE表單是執(zhí)行UPSERT的正確方法。
我將IF @@ROWCOUNT = 0在INSERT和UPDATE之間添加:
INSERT INTO <table>
SELECT <natural keys>, <other stuff...>
WHERE NOT EXISTS
-- no race condition here
( SELECT 1 FROM <table> WHERE <natural keys> )
IF @@ROWCOUNT = 0 BEGIN
UPDATE ...
WHERE <natural keys>
END
單個(gè)語(yǔ)句始終在事務(wù)中執(zhí)行,無論是它們自己(自動(dòng)提交和隱式),還是與其他語(yǔ)句(顯式)一起執(zhí)行。
- 3 回答
- 0 關(guān)注
- 625 瀏覽
添加回答
舉報(bào)