Я не уверен, почему в этих ответах так много дезинформации, но ответ прост (даже если речь идет о продвинутой теме SQL). Вот для чего нужна «блокировка» практически в любой СУБД. Точный синтаксис зависит от поставщика и версии, а некоторые предлагают синтаксис, который пытается скрыть блокировку от пользователя (как правило, когда выбор и обновление находятся в одном запросе).
Для MySQL вы сначала должны использовать SELECT ... FROM ... FOR UPDATE;
, который говорит базе данных устанавливать эксклюзивную блокировку для каждой возвращаемой записи.
Важно не блокируйте больше строк, чем вам абсолютно необходимо! Сделайте запрос «SELECT FOR UPDATE» настолько гранулированным, насколько это возможно, с либеральным использованием предложений «WHERE» и «LIMIT».
Впоследствии, когда то же соединение с базой данных выдает UPDATE ...
для тех же строк, которые были ранее заблокированы, эта блокировка снимается, и другие могут снова получить доступ к этой строке.
Допустим, у вас есть очередь заданий с полем «СОСТОЯНИЕ», которое используется для установки состояния выполнения каждого задания. 0 для очереди, 1 для выполнения, 2 для выполнения, 3 для отказа и т. Д.
Каждый бегун мог атомарно получить задание для выполнения (чтобы два бегуна не пытались выполнить одно и то же задание), выполнив следующее:
SELECT ID, * FROM JOBS WHERE STATUS = 0 LIMIT 1 FOR UPDATE;
тогда
UPDATE JOBS SET STATUS = 1 WHERE JOBS.ID = X;
тогда он может запустить задание и обновить базу данных, когда закончите:
UPDATE JOBS SET STATUS = [2|3] WHERE JOBS.ID = X;
Важно
Из документации MySQL:
Все блокировки, установленные запросами LOCK IN SHARE MODE и FOR UPDATE, снимаются при фиксации или откате транзакции.
SELECT FOR UPDATE
не блокирует записи, если включен автокоммит. Отключите автокоммит или (желательно), используя START TRANSACTION; SELECT ... FROM ... FOR UPDATE; UPDATE ...; END TRANSACTION;