INSERT INTO ... SELECT 导致死锁

问题描述 投票:0回答:1

我有一个包含时间相关数据的表格。想想天气数据 - 一次插入的某些数据可能与更早时间插入的数据相同。

我的案例唯一的独创性是,如果 由同一个人提供的最新数据是相同的,我不希望插入数据。

我的表格如下(编辑和更正)

  • dataid,主键,BINARY(16)。其他表有一个引用该主键的外键。
  • personid,这是另一个表上的外键
  • 时间,
  • 第 1 列,
  • col2

我有以下查询尝试执行我想要的操作:

INSERT INTO table
SELECT :dataid, :personid, :col1, :col2
WHERE NOT EXISTS (SELECT * FROM table WHERE person=:personid, col1=:col1, col2=:col2 ORDER BY time DESC LIMIT 1)

此查询旨在当且仅当表中

:personid
的最新行(如果有)尚不具有值
:col1, :col2
时才插入行。该查询预计会很快,因为尽管表很大,但
:personid
特定的数据不会超过几百行。

大多数情况下,此查询会成功。但是,有时会引发以下错误:

SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction

(我的查询是作为可重复读取事务的一部分执行的,我目前无法控制该事务。)

造成这种行为的原因是什么以及如何避免?我想知道这是否与我使用

personid
(外键)这一事实无关。

编辑:该表还有一个 BINARY(16) 主键。该键在数据库的其他表中使用 FOREIGN KEYS 引用。

sql mariadb mariadb-10.4
1个回答
0
投票

由于您已经排除了 FK 导致锁定的情况:

CREATE INDEX IF NOT EXISTS xi_table 
ON table(personid, col1, col2, time)
© www.soinside.com 2019 - 2024. All rights reserved.