首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >插入操作会导致死锁吗?

插入操作会导致死锁吗?
EN

Stack Overflow用户
提问于 2013-05-14 02:42:11
回答 3查看 46.2K关注 0票数 28

假设:

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

我有以下问题:

  1. INSERT 操作有可能导致死锁吗?如果可能,请提供一个详细的场景说明死锁是如何发生的(例如线程1执行死锁,线程2执行死锁)。
  2. 加分:回答所有其他操作的相同问题(例如选择、更新、删除)。

UPDATE:3.关于超级奖励点:在下面的场景中我如何避免死锁?

给出的表格:

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

我创建一个新的公司如下:

  • 插入权限;--插入permissions.id = 100
  • 插入公司(名称,permission_id)值(‘任天堂’,100);-插入companies.id = 200

我删除一家公司如下:

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

在上面的示例中,插入锁定顺序是权限,而删除锁定顺序是公司权限。是否有方法修复此示例以用于REPEATABLE_READSERIALIZABLE隔离?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-14 03:49:55

通常,所有的修改都会导致死锁,而selects不会(稍后再进行)。所以

  1. 不,你不能忽视这些。
  2. 根据数据库和设置,您可以忽略select,但其他设置会给您带来死锁。

你甚至不需要多张桌子。

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

Server示例:

代码语言:javascript
复制
create table A
(
    PK int primary key
)

第1场会议:

代码语言:javascript
复制
begin transaction
insert into A values(1)

第2场会议:

代码语言:javascript
复制
begin transaction    
insert into A values(7)

第1场会议:

代码语言:javascript
复制
delete from A where PK=7

第2场会议:

代码语言:javascript
复制
delete from A where PK=1

你会陷入僵局。因此,这证明了插入和删除可以死锁。

更新类似:

第1场会议:

代码语言:javascript
复制
begin transaction    
insert into A values(1)
insert into A values(2)
commit

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

第2场会议:

代码语言:javascript
复制
begin transaction
update A set pk=9 where pk=2    
update A set pk=8 where pk=1

第1场会议:

代码语言:javascript
复制
update A set pk=9 where pk=2

死锁!

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

如果使用快照隔离,Server将不会锁定选择。Oracle &我认为Postgres永远不会锁定SELECT (除非您有UPDATE,这显然是在为更新保留)。

所以基本上我认为你有一些错误的假设。我想我已经证明:

  1. 更新会导致死锁。
  2. 删除会导致死锁。
  3. 插入会导致死锁。
  4. 您不需要多张桌子。
  5. do需要多个会话

您只需在SELECT上接受我的话;)但是它将取决于您的DB和设置。

票数 34
EN

Stack Overflow用户

发布于 2016-04-28 08:28:13

除了LoztInSpace的答案之外,inserts甚至在没有deletesupdates的情况下也可能导致死锁。您所需要的只是一个唯一的索引和一个反转的操作顺序。

Oracle中的示例:

代码语言:javascript
复制
create table t1 (id number);
create unique index t1_pk on t1 (id);

--thread 1 :
insert into t1 values(1);
--thread 2
insert into t1 values(2);
--thread 1 :
insert into t1 values(2);
--thread 2
insert into t1 values(1);  -- deadlock !
票数 13
EN

Stack Overflow用户

发布于 2013-05-14 02:58:01

让我们假设您有两个关系AB以及两个用户XY。表A被用户X锁定,表B被Y锁定。如果用户X和Y同时使用,下面的查询将给您一个死锁。

代码语言:javascript
复制
Select * from A,B

因此,显然,如果涉及多个表的联接操作是Select操作的一部分,则会导致死锁。通常,插入和删除操作涉及单个关系。所以他们可能不会造成僵局。

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

https://stackoverflow.com/questions/16534277

复制
相关文章

相似问题

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