首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否在delete\insert事务中避免主键冲突?

是否在delete\insert事务中避免主键冲突?
EN

Stack Overflow用户
提问于 2021-02-20 01:43:12
回答 1查看 64关注 0票数 0

我有一个非常简单的T-SQL查询

代码语言:javascript
运行
复制
DELETE FROM my_table
WHERE [id] = @Id

INSERT INTO my_table
    ([id], [payload])
VALUES
    (@Id, @Payload)

很多这样的查询都是在不同的线程中执行的。INSERT和DELETE位于

事务

with类型

已提交读取

..。每件事在99.9%的时间里都工作得很好,但当它失败的时候有一个边缘情况:

代码语言:javascript
运行
复制
Violation of PRIMARY KEY constraint 'PK_my_table'. Cannot insert duplicate key in object 'dbo.my_table'. The duplicate key value is (9).
The statement has been terminated.

出现以下情况时会出现问题:

我们有2个交易具有相同的@Id

表my中没有@Id的记录

_

表格

因此,第一个和第二个事务以DELETE开始。两个事务都不会删除任何内容,因为表my中没有记录

_

表格。两个都开始插入,并且都违反了主键。

问题是如何避免这种情况

读取提交的事务类型

不使用MERGE语句

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-20 02:32:58

我们有2个具有相同@Id的交易记录我们在表my中没有带有@Id的记录

_

表格

这就是范围锁定要解决的场景。在SERIALIZABLE或HOLDLOCK提示下,您将在空键范围上使用键范围锁。

例如

代码语言:javascript
运行
复制
drop table if exists tt
go
create table tt(id int primary key, a int)

begin transaction
    delete from tt 
    where id = 1
    select resource_type, request_mode, request_status
    from sys.dm_tran_locks
    where request_session_id = @@spid 
commit transaction

go

begin transaction
    delete from tt with (holdlock) 
    where id = 1
    select resource_type, request_mode, request_status
    from sys.dm_tran_locks
    where request_session_id = @@spid 
commit transaction

输出

代码语言:javascript
运行
复制
(0 rows affected)
resource_type                                                request_mode                                                 request_status
------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------
OBJECT                                                       IX                                                           GRANT

(1 row affected)


(0 rows affected)
resource_type                                                request_mode                                                 request_status
------------------------------------------------------------ ------------------------------------------------------------ ------------------------------------------------------------
KEY                                                          RangeX-X                                                     GRANT
OBJECT                                                       IX                                                           GRANT

(2 rows affected)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66282479

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档