mysql - mysql多次批量更新操作死锁

标签 mysql sql-update deadlock

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

我得到的异常(exception)是

com.mysql.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

最佳答案

简短回答:

yes, the probability would decrease

长答案:

让我们弄清楚为什么会发生死锁。当您更新一行时,会在此特定行上设置排他锁,并且它将一直保留到您的事务提交/回滚为止。 这意味着,没有其他事务可以更新它——它只会阻塞,直到事务完成。当 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

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

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

关于mysql - mysql多次批量更新操作死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26006298/

相关文章:

mysql - 操作 VARCHAR 字符串并更新列(伪日期)

c# - 使用 Windbg 的 !clrstack 命令调试死锁

mysql - "Multiple SELECT, INNER JOIN"SQL查询不起作用

php - 另一个就地编辑器——一个 jQuery 就地编辑插件

Mysql根据列总和结果选择列

php - $mysqli->fetch_array();返回奇怪的结果

mysql - 如何确定更新语句中导致 "Cannot add or update a child row"的值是什么?

php - 使用单个查询更新多行

sql-server-2005 - SQL Server 2005 中的死锁!两个实时批量更新正在战斗。为什么?

c - 有人有非异步安全信号处理程序死锁的示例吗