sql – INSERT操作是否会导致死锁?

前端之家收集整理的这篇文章主要介绍了sql – INSERT操作是否会导致死锁?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设:

>我使用REPEATABLE_READ或SERIALIZABLE事务隔离(每次访问一个行时,锁都会保留)
>我们正在谈论同时访问多个表的多个线程.

我有以下问题:

> INSERT操作是否可能导致死锁?如果是这样,请提供详细的场景,说明如何发生死锁(例如,线程1执行此操作,线程2执行此操作,死锁).
>对于奖励积分:对所有其他操作(例如SELECT,UPDATE,DELETE)回答相同的问题.

更新:
3.对于超级奖励积分:如何在以下情况下避免死锁?

给定表:

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

我创建一个新公司如下:

> INSERT INTO权限; – 插入permissions.id = 100
> INSERT INTO companies(name,permission_id)VALUES(“Nintendo”,100); – 插入company.id = 200

删除公司如下:

> SELECT permission_id FROM COMPANY WHERE id = 200; – 返回permission_id = 100
> DELETE FROM companies WHERE id = 200;
> DELETE FROM权限WHERE id = 100;

在上面的例子中,INSERT锁定顺序是[权限,公司],而DELETE锁定顺序是[公司,权限].有没有办法解决这个示例REPEATABLE_READ或SERIALIZABLE隔离?

解决方法

通常所有修改都可能导致死锁,并且选择不会(稍后再进行).所以

>不,你不能忽视这些.
>你可以根据你的数据库和设置有点忽略选择,但其他的会给你死锁.

你甚至不需要多个表.

创建僵局的最佳方法是以不同的顺序执行相同的操作.

sql Server示例:

create table A
(
    PK int primary key
)

会议1:

begin transaction
insert into A values(1)

会话2:

begin transaction    
insert into A values(7)

会议1:

delete from A where PK=7

会话2:

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

会话2:

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隔离,sql Server将不会锁定在SELECT上. Oracle&我认为Postgres永远不会锁定SELECT(除非你有明确保留更新的FOR UPDATE).

所以基本上我觉得你有一些不正确的假设.我想我已经证明:

>更新可能会导致死锁
>删除可能会导致死锁
>插入可能导致死锁
>你不需要多于一个表
>你需要多个会话

您只需要在SELECT上使用我的单词),但它将取决于您的数据库和设置.

猜你在找的MsSQL相关文章