2014-09-23 2 views
1

Я получаю следующее исключение, когда пытаюсь выполнить пакетное обновление. В то же время выполняется несколько потоков, которые могут обращаться к строке в базе данных. Я делаю несколько пакетных обновлений. Может ли кто-нибудь прокомментировать связь между размером партии и тупиком? Уменьшая размер партии (в настоящее время размер партии = 1000), уменьшится ли вероятность тупика?Тупик mysql несколько операций пакетного обновления

Исключение я получаю

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

Они обновляют те же строки? – zerkms

+0

Да, это может произойти, я фильтрую некоторые строки в where where, но – comeOnGetIt

+0

Если вы обновляете те же строки, что определенно может вызвать взаимоблокировки. – zerkms

ответ

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/

Смежные вопросы