回答

收藏

INSERT操作会导致死锁吗?

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

假设:
) A0 g4 Y5 g) o3 k7 X; z4 y+ B- L3 j我正在使用REPEATABLE_READ或SERIALIZABLE事务隔离(每次访问都会保留锁); Y" S" Y8 `" M, I' n1 S2 R$ w
在访问多个表的同时,我们正在讨论多个线程。
我有以下问题:+ G; C( l$ N. o8 G
[ol]操作是否可能INSERT导致死锁?如果是这样,请提供一个详细的场景来演示如何发生死锁(例如,线程1会这样做,线程2会这样做,…,死锁)。' b6 F4 w# O3 }+ L' R% l
为所有其他操作获得加分(如SELECT,UPDATE,DELETE)回答同样的问题。[/ol]更新    :3.超级奖励积分:在以下情况下如何避免僵局?1 T  X+ P- a7 U5 ~, n* M
给定表:
$ h" b9 |) \+ M2 i权限[id BIGINT PRIMARY KEY]
* s1 r: E  c) V% C5 z" O的公司[id BIGINT PRIMARY KEY,name VARCHAR(30),permission_id BIGINT NOT NULL,FOREIGN KEY (permission_id) REFERENCES permissions(id))
我创办了一家新公司,如下所示:
1 d& R3 q2 |  k/ LINSERT INTO权限;-插入Permissions.id = 100
* R$ o4 t5 Q7 a; E% R2 |1 {) DINSERT INTO公司(名称,permission_id)VALUES(“ Nintendo”,100);-插入companies.id = 200
删除公司如下:5 E( }& J% P' V6 h: u
在公司ID = 选择200家公司Permission_id -返回Permissions_id = 100
7 b# U. C# d4 q+ G从ID删除200家公司;- Y) p" I9 W: K' v
从ID删除100权限;
在上述示例中,INSERT锁定顺序为[权限,公司],而DELETE锁定顺序是[公司,权限]。有没有办法解决这个例子的问题?REPEATABLE_READ或SERIALIZABLE隔离?  P/ h( \4 A. p! g% v/ I# C
                                                               
) m; E. J+ r4 W& A7 j' }    解决方案:                                                                9 G4 h4 x1 U# g1 L
                                                                通常,所有的修改都可能导致死锁,但选择不会(稍后介绍)。8 H' P: r! ?$ G8 s
[ol]不,你不能忽视这些。2 i6 K- w) C9 u* a! T
您可以根据数据库和设置忽略选择,但其他选择会给您带来僵局。[/ol]你甚至不需要多个表。
1 z/ `. u; H/ V) G# a6 `# d产生死锁的最佳方法是按不同的顺序执行相同的操作。
0 ?; H5 m1 G: I4 |* P4 eSQL Server示例:
$ V+ u0 S7 S7 w: N9 Mcreate table A(    PK int primary key)第一场:
# N% b8 x9 h" R) ~# k0 ^2 ybegin transactioninsert into A values(1)第二场:3 A5 A2 Q% l) m# }& Q' F
begin transaction    insert into A values(7)第一场:7 |! Z) _  h& H
delete from A where PK=7第二场:
+ ?+ m0 @: f3 C6 H, o6 gdelete from A where PK=1你将陷入僵局。这证明了插入和删除可能会死锁。
9 L- @, E) B' r  |, k) r9 O更新类似:8 M8 K  d5 }4 h9 q
第一场:4 T* d$ |2 B1 R/ `- ~# m
begin transaction    insert into A values(1)insert into A values(2)commitbegin transactionupdate A set PK=7 where PK=1第二场:
0 x- l7 S! w' `begin transactionupdate A set pk=9 where pk=2    update A set pk=8 where pk=1第一场:3 u- n( s& S6 D1 \/ ?. j, c
update A set pk=9 where pk=2僵局!% d; J0 V; @. _  a% Y+ d3 _
SELECT永远不要死锁,但它会在某些数据库上死锁,因为它使用的锁会干扰一致的读取。但这只是数据库引擎设计的一个糟糕方法。
& N! g* g/ o" Q0 l如果您使用SNAPSHOT ISOLATION,则SQL& [4 P2 G0 M' @# p/ o9 F  z( |- i
Server将不会锁定SELECT。Oracle&我认为Postgres永远不会锁定SELECT(除非你有FOR
$ F9 R, Z5 m# W/ AUPDATE,无论如何,它显然保留了更新)。
! J# y9 f. L$ G; B所以,基本上我觉得你有一些错误的假设。我想我已经证明了:
; P. `2 L, h. L1 d[ol]更新可能导致死锁
0 \, P0 z- R* K) A- A删除可能导致死锁9 _& a& T" A' F
插入会导致死锁; c9 [; _. c& ]
你不需要多张桌子
6 W- U4 S+ X! q确实    需要多次会议[/ol]你只需要相信SELECT;),但这取决于你的数据库和设置。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则