Gil*_*ili 22 sql deadlock insert
假设:
我有以下问题:
INSERT导致死锁?如果是这样,请提供一个详细的场景,演示如何发生死锁(例如,线程1执行此操作,线程2执行此操作,...,死锁).更新:3.对于超级奖励积分:如何在以下场景中避免死锁?
给定表格:
[id BIGINT PRIMARY KEY][id BIGINT PRIMARY KEY, name VARCHAR(30), permission_id BIGINT NOT NULL, FOREIGN KEY (permission_id) REFERENCES permissions(id))我按如下方式创建了一家新公司:
我删除公司如下:
在上面的示例中,INSERT锁定顺序是[permissions,companies],而DELETE锁定顺序是[companies,permissions].有没有办法解决这个例子REPEATABLE_READ或SERIALIZABLE隔离?
Loz*_*ace 29
通常,所有修改都可能导致死锁,而选择则不会(稍后再说).所以
你甚至不需要多个表.
创建死锁的最佳方法是以不同的顺序执行相同的操作.
SQL Server示例:
create table A
(
PK int primary key
)
Run Code Online (Sandbox Code Playgroud)
第一节:
begin transaction
insert into A values(1)
Run Code Online (Sandbox Code Playgroud)
第二节:
begin transaction
insert into A values(7)
Run Code Online (Sandbox Code Playgroud)
第一节:
delete from A where PK=7
Run Code Online (Sandbox Code Playgroud)
第二节:
delete from A where PK=1
Run Code Online (Sandbox Code Playgroud)
你会陷入僵局.因此,证明插入和删除可能会死锁.
更新类似:
第一节:
begin transaction
insert into A values(1)
insert into A values(2)
commit
begin transaction
update A set PK=7 where PK=1
Run Code Online (Sandbox Code Playgroud)
第二节:
begin transaction
update A set pk=9 where pk=2
update A set pk=8 where pk=1
Run Code Online (Sandbox Code Playgroud)
第一节:
update A set pk=9 where pk=2
Run Code Online (Sandbox Code Playgroud)
僵局!
SELECT永远不应该死锁,但在某些数据库上它会因为它使用的锁会干扰一致的读取.这只是糟糕的数据库引擎设计.
如果使用SNAPSHOT ISOLATION,SQL Server将不会锁定SELECT.Oracle和我认为Postgres永远不会锁定SELECT(除非你有FOR UPDATE,无论如何都明确保留了更新).
所以基本上我认为你有一些不正确的假设.我想我已证明:
你只需要对SELECT;)进行说明,但这取决于你的数据库和设置.
除了LoztInSpace的答案之外,inserts即使没有deletes或updates存在也可能导致死锁.您所需要的只是一个独特的索引和一个颠倒的操作顺序.
Oracle中的示例:
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 !
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30725 次 |
| 最近记录: |