回答

收藏

INSERT操作会导致死锁吗?

技术问答 技术问答 650 人阅读 | 0 人回复 | 2023-09-14

假设:
6 M+ R; _# i7 O" w! K& P我正在使用REPEATABLE_READ或SERIALIZABLE事务隔离(每次访问都会保留锁)( y# k; k: k; f$ n+ p
在访问多个表的同时,我们正在讨论多个线程。
我有以下问题:5 q- H% y' L- L* C" y
[ol]操作是否可能INSERT导致死锁?如果是这样,请提供一个详细的场景来演示如何发生死锁(例如,线程1会这样做,线程2会这样做,…,死锁)。
; x4 b$ x; D! q/ o* Q) D为所有其他操作获得加分(如SELECT,UPDATE,DELETE)回答同样的问题。[/ol]更新    :3.超级奖励积分:在以下情况下如何避免僵局?
2 ?+ {+ ^: `+ J& S9 q, b给定表:
) j$ C3 w1 k+ `( s+ M# C$ v% J权限[id BIGINT PRIMARY KEY]
+ H1 Z" U; v& Y( `/ r" e/ c1 S7 H的公司[id BIGINT PRIMARY KEY,name VARCHAR(30),permission_id BIGINT NOT NULL,FOREIGN KEY (permission_id) REFERENCES permissions(id))
我创办了一家新公司,如下所示:
) j! _5 ^* d/ ]' |. ^9 OINSERT INTO权限;-插入Permissions.id = 100
7 C) F4 _; _+ M- u/ p8 z/ TINSERT INTO公司(名称,permission_id)VALUES(“ Nintendo”,100);-插入companies.id = 200
删除公司如下:
+ O7 k  L7 n- j" M, i3 |5 g在公司ID = 选择200家公司Permission_id -返回Permissions_id = 100
6 G- k3 n& H) P' S8 S% A" ]从ID删除200家公司;
* h, s* b2 T6 D; X从ID删除100权限;
在上述示例中,INSERT锁定顺序为[权限,公司],而DELETE锁定顺序是[公司,权限]。有没有办法解决这个例子的问题?REPEATABLE_READ或SERIALIZABLE隔离?* F. K( |$ E1 B3 j, a4 b
                                                               
$ u  \# e" P0 J2 n2 V6 j    解决方案:                                                                3 y/ \  g) P6 E) F- [* i
                                                                通常,所有的修改都可能导致死锁,但选择不会(稍后介绍)。
4 d! ~6 {- g! Z! x, I[ol]不,你不能忽视这些。4 P* k; g6 r* v+ k- H
您可以根据数据库和设置忽略选择,但其他选择会给您带来僵局。[/ol]你甚至不需要多个表。; r: P" ?7 t/ f. ^$ W
产生死锁的最佳方法是按不同的顺序执行相同的操作。0 }$ ]3 h" p* H  r: s  z9 x1 Q
SQL Server示例:
. i5 y& }+ N! Q- r6 qcreate table A(    PK int primary key)第一场:
: V" o- b4 l% W# ~begin transactioninsert into A values(1)第二场:7 @' p8 w1 f3 E9 i3 L: o& V$ }
begin transaction    insert into A values(7)第一场:
) H& ~* W2 E) Z8 M7 f0 `delete from A where PK=7第二场:
9 j3 y7 J% }; q5 tdelete from A where PK=1你将陷入僵局。这证明了插入和删除可能会死锁。
0 S  V7 L  q+ h: J更新类似:
4 R9 e( [' x, I( L( [! z- Q5 o. E第一场:" o6 o" _: F& m! E3 ]6 h
begin transaction    insert into A values(1)insert into A values(2)commitbegin transactionupdate A set PK=7 where PK=1第二场:
8 P: w. ?9 L5 e2 Kbegin transactionupdate A set pk=9 where pk=2    update A set pk=8 where pk=1第一场:
8 y- x' P( w2 e6 p% b4 Z) mupdate A set pk=9 where pk=2僵局!
" J9 U6 ~7 U- W! `$ VSELECT永远不要死锁,但它会在某些数据库上死锁,因为它使用的锁会干扰一致的读取。但这只是数据库引擎设计的一个糟糕方法。
; Q  R# Q; o) Y. x如果您使用SNAPSHOT ISOLATION,则SQL
4 x% `+ T' A4 QServer将不会锁定SELECT。Oracle&我认为Postgres永远不会锁定SELECT(除非你有FOR  D) A0 ]  A  N2 M
UPDATE,无论如何,它显然保留了更新)。9 h' N) e* H, p' o- @) f
所以,基本上我觉得你有一些错误的假设。我想我已经证明了:" {. X3 Q3 U! Y1 S! T7 @6 r
[ol]更新可能导致死锁
' J( o, p  s+ J; \8 n0 C删除可能导致死锁
+ `* p2 I- p" q# `# Y插入会导致死锁3 M4 {: e9 S: j
你不需要多张桌子
- S. ^$ f( T0 V0 ^( ~. q确实    需要多次会议[/ol]你只需要相信SELECT;),但这取决于你的数据库和设置。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则