回答

收藏

INSERT操作会导致死锁吗?

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

假设:! F- M. G3 o7 X' M
我正在使用REPEATABLE_READ或SERIALIZABLE事务隔离(每次访问都会保留锁); `/ p, g6 M3 J6 |% [
在访问多个表的同时,我们正在讨论多个线程。
我有以下问题:  D! V# r, D% I9 ?8 d0 R9 }- g5 e
[ol]操作是否可能INSERT导致死锁?如果是这样,请提供一个详细的场景来演示如何发生死锁(例如,线程1会这样做,线程2会这样做,…,死锁)。
/ U1 {; B9 k1 J% L为所有其他操作获得加分(如SELECT,UPDATE,DELETE)回答同样的问题。[/ol]更新    :3.超级奖励积分:在以下情况下如何避免僵局?
; q8 S/ {: n5 Q给定表:
, b6 Q$ w* L/ o7 M权限[id BIGINT PRIMARY KEY]7 I% X8 b) E' y1 w4 q# |
的公司[id BIGINT PRIMARY KEY,name VARCHAR(30),permission_id BIGINT NOT NULL,FOREIGN KEY (permission_id) REFERENCES permissions(id))
我创办了一家新公司,如下所示:
8 ~% S* s+ `! Z3 d" t, H& p4 MINSERT INTO权限;-插入Permissions.id = 1009 S5 _3 ]5 ?0 K0 A3 D; y5 f
INSERT INTO公司(名称,permission_id)VALUES(“ Nintendo”,100);-插入companies.id = 200
删除公司如下:
) X) S2 E6 ]0 D: f- s. P; K4 h" J* C. P( {在公司ID = 选择200家公司Permission_id -返回Permissions_id = 100
, G( ]- B2 g7 C9 p* l0 c& U1 D  `' x从ID删除200家公司;
; o, G- z* Z% ^! g" |4 O& w从ID删除100权限;
在上述示例中,INSERT锁定顺序为[权限,公司],而DELETE锁定顺序是[公司,权限]。有没有办法解决这个例子的问题?REPEATABLE_READ或SERIALIZABLE隔离?
5 P# Y4 ^( M& u2 g9 C0 ]+ l                                                                7 ?, }; Z! t2 b- n" E6 v
    解决方案:                                                               
5 S7 M- }+ F4 Q* c. k' l; D                                                                通常,所有的修改都可能导致死锁,但选择不会(稍后介绍)。
5 P- Y7 x" c* d2 h[ol]不,你不能忽视这些。% c" S$ g9 N$ |1 U  T1 K6 U
您可以根据数据库和设置忽略选择,但其他选择会给您带来僵局。[/ol]你甚至不需要多个表。% v: q# q4 V6 E9 u+ m1 f' V
产生死锁的最佳方法是按不同的顺序执行相同的操作。6 U% Q- a. V, E" B4 V" W
SQL Server示例:
5 e: _' F9 Y7 Ocreate table A(    PK int primary key)第一场:
( Q& Q7 {' f$ {) tbegin transactioninsert into A values(1)第二场:
' `, A8 G, r2 m0 O: r. |7 ?7 Nbegin transaction    insert into A values(7)第一场:* w& t9 S: |% ^
delete from A where PK=7第二场:
1 a% s* i: Q+ f! c" b+ fdelete from A where PK=1你将陷入僵局。这证明了插入和删除可能会死锁。
5 o4 U, c: b& i9 P0 b更新类似:
; n0 N2 n" U" L3 O3 @3 ?第一场:  C& \$ u2 m! S) d
begin transaction    insert into A values(1)insert into A values(2)commitbegin transactionupdate A set PK=7 where PK=1第二场:; V% n5 S0 u3 ?) G0 d3 n3 a! l8 y4 e
begin transactionupdate A set pk=9 where pk=2    update A set pk=8 where pk=1第一场:
, l5 Z8 g% L% j2 Iupdate A set pk=9 where pk=2僵局!
5 C' \& Y* M  C* e: ^& P' XSELECT永远不要死锁,但它会在某些数据库上死锁,因为它使用的锁会干扰一致的读取。但这只是数据库引擎设计的一个糟糕方法。
4 O# _0 w3 G; y如果您使用SNAPSHOT ISOLATION,则SQL9 Z1 R( M9 d, t6 v& u  w/ z& v. l
Server将不会锁定SELECT。Oracle&我认为Postgres永远不会锁定SELECT(除非你有FOR! X, G8 n+ S4 M1 [$ q) B+ ?, q
UPDATE,无论如何,它显然保留了更新)。
: L# j+ Q* \5 P" r/ R所以,基本上我觉得你有一些错误的假设。我想我已经证明了:
: \% e8 R. \$ M: `* H' t[ol]更新可能导致死锁" F" p7 @) T4 q7 L7 @8 A' j
删除可能导致死锁- ~8 l4 k3 y  [. R8 e
插入会导致死锁
5 Y5 D8 W0 Q' [4 U' B* i你不需要多张桌子( f$ W$ [0 P$ D7 U  q- }- ^
确实    需要多次会议[/ol]你只需要相信SELECT;),但这取决于你的数据库和设置。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则