mysql多次批量更新操作死锁

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

当我尝试进行批量更新时,出现以下异常。有多个线程同时运行,可能正在访问数据库中的一行。我正在进行多次批量更新。谁能评论一下批量大小和死锁之间的关系吗?通过减小batch size(目前batch size = 1000),死锁的概率会降低吗?

我得到的例外是

com.mysql.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
mysql sql-update deadlock
1个回答
2
投票

简短回答

是的,概率会降低

长答案

让我们弄清楚为什么会发生死锁。当您更新一行时,会在此特定行上设置排他锁,并且它将一直保留到您的事务提交/回滚为止。 这意味着,没有其他事务可以更新它——它只会阻塞,直到事务完成。当 tran1 愿意锁定 tran2 持有的行,而 tran2 又已经在等待 tran1

锁定的某些行时,就会发生死锁

这是一个例子:

MariaDB [test]> create table a (id int primary key, value int);
Query OK, 0 rows affected (0.14 sec)

MariaDB [test]> insert into a values (1, 0), (2, 0), (3, 0), (4, 0);
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql console 1:
step 1> start transaction;
step 3> update a set value = 1 where id = 2;
step 5> update a set value = 1 where id = 1;

mysql console 2:
step 2> start transaction;
step 4> update a set value = 1 where id = 1;
step 6> update a set value = 1 where id = 2;

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

每次批量更新期间接触(=更新)的行越多,发生此类冲突的概率就越高。

您可以通过以明确定义的顺序遍历行来降低这种概率。在这种情况下,我提供的简单示例将不可行。 有关避免死锁的更多详细信息,请参阅这篇精彩文章: https://web.archive.org/web/20161015235352/https://www.xaprb.com/blog/2006/08/03/a-little-known-way-to-cause-a-database-deadlock /

© www.soinside.com 2019 - 2024. All rights reserved.