Назад | Перейти на главную страницу

Могут ли транзакции выполняться последовательно в MySQL?

Допустим, у меня есть два сервера, которые одновременно инициируют транзакцию в базе данных MySQL 5.5 с помощью InnoDB. Обе транзакции делают одно и то же: читают одну строку, а затем обновляют строку в зависимости от ее содержимого. Я хочу убедиться, что две транзакции выполняются одна за другой. То есть, второй транзакции не должно быть разрешено читать строку, пока первая транзакция не будет завершена. В идеале это означало бы, что SELECT Оператор во второй транзакции будет ждать, пока первая транзакция не будет зафиксирована, а затем вернет обновленные значения.

Это возможно? Если нет, есть ли база данных, которая лучше подходит для этой задачи, чем MySQL?

Если да, то связанный с этим вопрос: предположим, что первый сервер вышел из строя во время транзакции, поэтому нет COMMIT сообщение когда-либо было получено. Как мне установить тайм-аут, после которого транзакция автоматически откатится, чтобы вторая транзакция не откладывалась навсегда? (Обновить: Я выделил это как отдельный вопрос.)

Хорошо, я принял предложение Шейна и превратил его в тестовый пример. У меня есть таблица под названием nsync со строкой с id 1 и ценность foo. Затем я запускаю эту транзакцию:

START TRANSACTION;
SELECT * FROM nsync WHERE id = '1' FOR UPDATE;
SELECT SLEEP(10);
UPDATE nsync SET stringy = 'bar' WHERE id = '1';
COMMIT;

и во время сна я бегу

SELECT * FROM nsync WHERE id = '1' FOR UPDATE;

Оно работает! В SELECT ожидает завершения первой транзакции и возвращает обновленное значение bar.

Обратите внимание, что важно, чтобы обе SELECT заявления используют FOR UPDATE; если первый SELECT не использовал его, тогда строка не будет заблокирована; а если второй SELECT не использовал его, он не заботился о замке.

SELECT ... FOR UPDATE может удовлетворить ваши потребности. Посмотреть здесь.