选择更新并在重复密钥更新时插入会导致mysql中同一行插入的死锁

bvk5enib  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(350)

我正在并发执行多个事务,当通过SELECTFORUPDATE查询检查同一行时,会出现这样的情况,并且使用insert on duplicate key update插入或更新同一行。但这会导致僵局。
这是表模式

CREATE TABLE `t` (
  `a` varchar(40) NOT NULL,
  `b` date NOT NULL,
  `c` enum('a','b') COLLATE utf8_bin NOT NULL,
  `d` char(12) NOT NULL,
  `e` TINYINT(1) UNSIGNED NOT NULL,
  PRIMARY KEY (`a, `b`, `c`, `d` )
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

以下是事务操作。
在事务1中:

Start Transaction;

SELECT  *
FROM t
WHERE
    a= '123'
        AND `b` = '2017-01-01'
        AND c= 'a'
        AND d= '1'
FOR UPDATE;

INSERT INTO t
(`a`, b, `c` , d, e)
VALUES ('123', '2017-01-01', 'a' , '1'  , '2')
ON DUPLICATE KEY UPDATE `e` = '2';

Commit;

在事务2中:

Start Transaction;

SELECT  *
FROM t
WHERE
    a= '123'
        AND `b` = '2017-01-01'
        AND c= 'a'
        AND d= '1'
FOR UPDATE;

INSERT INTO t
(`a`, b, `c` , d, e)
VALUES ('123', '2017-01-01', 'a' , '1'  , '2')
ON DUPLICATE KEY UPDATE `e` = '2';

Commit;

当两个事务都运行select进行更新,并且其中一个事务尝试插入行时,就会发生死锁。
注意:我需要为更新选择,因为在结果更新之前,我在上一个结果的基础上维护一个计数。由于插入而创建死锁。
问:我怎样才能避免僵局的问题?

ia2d9nvy

ia2d9nvy1#

innodb的事务处理并不十分精确。为了提高性能,一些非死锁被视为死锁,因为发现其他死锁的努力不值得付出代价和代价。
接受它。重新启动被破坏的事务。

相关问题