当我尝试进行批量更新时,出现以下异常。有多个线程同时运行,可能正在访问数据库中的一行。我正在进行多次批量更新。谁能评论一下批量大小和死锁之间的关系吗?通过减小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/