多线程和批量插入MySQL中的表中的死锁

时间:2018-04-02 09:01:32

标签: mysql multithreading qt deadlock

我有一个程序(在本例中为QT),试图通过8个线程同时向source_names表中插入4000条记录:每个线程500条记录。

我的表格如下:

CREATE TABLE `source_names` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `source_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx` (`source_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=101952 DEFAULT CHARSET=latin1;

正如上面代码中所述,我的source_name列是UNIQUE

所以我有8个线程,每个线程同时执行这些代码:

INSERT IGNORE INTO source_names (source_name) VALUES ('a001'),('a002'),...,('a500')

如果存在重复的source_name,则会出现警告,不会发生任何事情。

但主要问题是有时会出现Deadlock错误,我无法处理它:

Deadlock found when trying to get lock; try restarting transaction QMYSQL3: Unable to execute statement

我认为这是因为UNIQUE列。如果我只使用一个线程就没有问题,但是如何用多个线程解决这个问题呢?

1 个答案:

答案 0 :(得分:1)

来自MySQL参考手册 https://dev.mysql.com/doc/refman/5.7/en/concurrent-inserts.html

  

如果有多个INSERT语句,它们将按顺序排队并执行,与SELECT语句同时执行。

由于MySQL不会同时插入记录,因此您可以使用单个线程并避免死锁。

如果必须具有INSERT的多线程,请考虑使用try-catch块。 如果发生死锁,请尝试再次插入。 如果你最终陷入无限循环,请放置一个计数器,不要试图永久插入。而是尝试仅插入预定义的时间(计数器)。