死锁mysql多次批量更新操作

时间:2014-09-23 23:34:21

标签: mysql sql-update deadlock

我尝试进行批量更新时遇到异常。有多个线程同时运行,可能正在访问数据库中的一行。我正在进行多次批量更新。任何人都可以评论批量大小和死锁之间的关系?通过减小批量大小(当前批量大小= 1000),死锁的概率是否会降低?

我得到的例外是

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

1 个答案:

答案 0 :(得分:0)

简短回答

  是的,概率会降低

长答案

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