gpt4 book ai didi

sql - INSERT 操作会导致死锁吗?

转载 作者:行者123 更新时间:2023-12-02 05:16:02 25 4
gpt4 key购买 nike

假设:

  • 我正在使用 REPEATABLE_READ 或 SERIALIZABLE 事务隔离(每次访问行时都会保留锁)
  • 我们讨论的是多个线程同时访问多个表。

我有以下问题:

  1. INSERT 操作是否可能导致死锁?如果是,请提供详细的场景来演示死锁是如何发生的(例如线程 1 执行此操作,线程 2 执行此操作,...,死锁)。
  2. 要获得奖励积分:针对所有其他操作(例如选择、更新、删除)回答相同的问题。

更新:3. 对于 super 积分:以下场景如何避免陷入僵局?

给定表格:

  • 权限[id BIGINT PRIMARY KEY]
  • 公司[id BIGINT PRIMARY KEY,名称 VARCHAR(30),permission_id BIGINT NOT NULL,FOREIGN KEY (permission_id) REFERENCES 权限(id))

我创建一个新公司如下:

  • 插入权限; -- 插入权限.id = 100
  • INSERT INTO 公司(名称,permission_id)VALUES('任天堂',100); -- 插入companys.id = 200

我按如下方式删除公司:

  • 从公司中选择permission_id,其中id = 200; -- 返回permission_id = 100
  • 从 id = 200 的公司中删除;
  • 从 id = 100 的权限中删除;

在上面的示例中,INSERT 锁定顺序是 [权限,公司],而 DELETE 锁定顺序是 [公司,权限]。有没有办法修复此示例以进行 REPEATABLE_READSERIALIZABLE 隔离?

最佳答案

一般来说,所有修改都会导致死锁,而选择则不会(稍后再讨论)。所以

  1. 不,你不能忽视这些。
  2. 您可以根据您的数据库和设置在某种程度上忽略 select,但其他选项会给您带来死锁。

您甚至不需要多个表。

造成死锁的最佳方法是以不同的顺序执行相同的操作。

SQL Server 示例:

create table A
(
PK int primary key
)

第 1 节:

begin transaction
insert into A values(1)

第二节:

begin transaction    
insert into A values(7)

第 1 节:

delete from A where PK=7

第二节:

delete from A where PK=1

你会陷入僵局。因此证明插入和删除可能会死锁。

更新类似:

第 1 节:

begin transaction    
insert into A values(1)
insert into A values(2)
commit

begin transaction
update A set PK=7 where PK=1

第二节:

begin transaction
update A set pk=9 where pk=2
update A set pk=8 where pk=1

第 1 节:

update A set pk=9 where pk=2

死锁!

SELECT 永远不应该死锁,但在某些数据库上它会死锁,因为它使用的锁会干扰一致性读取。但这只是蹩脚的数据库引擎设计。

如果您使用 SNAPSHOT ISOLATION,SQL Server 将不会锁定 SELECT。 Oracle 和我认为 Postgres 永远不会锁定 SELECT(除非你有 FOR UPDATE,它显然是为更新保留的)。

所以基本上我认为你有一些不正确的假设。我想我已经证明了:

  1. 更新可能导致死锁
  2. 删除可能会导致死锁
  3. 插入可能导致死锁
  4. 您不需要多于一张 table
  5. 确实需要多个 session

您只需相信我关于 SELECT 的话;)但这取决于您的数据库和设置。

关于sql - INSERT 操作会导致死锁吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16534277/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com