Сценарий:Как предотвратить взаимоблокировки базы данных в параллельных транзакциях?
транзакция А начинает ...
START TRANSACTION;
UPDATE table_name SET column_name=column_name+1 WHERE id = 1 LIMIT 1;
В то же время, сделка B начинается ...
START TRANSACTION;
UPDATE table_name SET column_name=column_name+1 WHERE id = 2 LIMIT 1;
UPDATE table_name SET column_name=column_name-1 WHERE id = 1 LIMIT 1;
COMMIT;
прямо сейчас, транзакция B ожидает строка 1, которая заблокирована в транзакции A.
И транзакция продолжается ...
UPDATE table_name SET column_name=column_name-1 WHERE id = 2 LIMIT 1;
COMMIT;
И теперь у нас есть мертвый замок, так что оба транзакции ожидают друг от друга, чтобы разблокировать строку, что они хотят, чтобы обновить: '(
Как я спросил в заголовке, как мы можем предотвратить взаимоблокировки в транзакции РСУБД?
Я думаю, что единственный способ исправить эту ситуацию - это откат транзакции B и ее повторное выполнение. Но как мы можем узнать, что мы находимся в тупике, и немедленно выходим из него, и как мы можем гарантировать, что мы не имеем запас и бесконечный цикл (например, в очень тяжелых веб-приложениях).
Если это необходимо, я использую MySQL. Но любое решение для других RDBMSs приветствуется - для помощи другим людям, приезжающим сюда из Google :)
Вы не можете предотвратить взаимоблокировки, однако вы можете написать код, который минимизирует их происхождение. – Shadow
@trincot Я думаю, что это транзакция A блокирует строку # 1, транзакция B блокирует строку №2 и ждет транзакции A, чтобы разблокировать строку # 1, а транзакция A ждет транзакции B, чтобы разблокировать строку №2, поэтому обе транзакции ждут друг для друга. Можете ли вы исправить меня, если я ошибаюсь? Благодарю. – user5483434
@Shadow Можете ли вы сообщить мне, как я могу свести к минимуму их присутствие? – user5483434