Блокировка на уровне строк - MySQL - для обновления
Я все еще запутался в блокировке строк таблицы. Я использую MySQL/PHP и вот мой сценарий.
У меня есть набор таблиц, которые мое приложение использует для отслеживания запросов и сообщений. Пользователь создает публикацию (таблица POSTING (P)) для элемента (таблица ITEM (I)) и может отправлять запросы отдельным пользователям (таблица REQUEST (R)) или может публиковать и получать ответы на сообщения (таблица POSTING_RESPONSE (PR))), которые будут приняты пользователем.
Пример: я пользователь с велосипедом. Я отправляю это - и также отсылаю запросы отдельным пользователям. Пользователи, которые получают запрос от меня, могут принять / отклонить / или ничего не делать. Если они принимают - это зарезервировано. Другие пользователи могут найти мои сообщения и "подать заявку" на товар. У меня есть возможность "принять" или "игнорировать" их запрос. Если я принимаю, товар зарезервирован.
Что я хочу сделать, если кто-то принимает запрос:
заблокировать строку в таблице ITEM (I), соответствующую позиции
заблокировать строку в таблице POSTING (P) (если строка существует), соответствующую элементу
блокировка строк в таблице REQUEST (R) для любых запросов, отправленных на элемент
блокировка строк в таблице POSTING_RESPONSE (PR) (если строки существуют), соответствующих элементу
обновить статус пункта на "Зарезервировано"
обновить статус POSTING на "Недоступно"
обновить все / любые POSTING_RESPONSE до "Отклонено"
обновить все ЗАПРОС на "Отклонено", кроме того, который принял - обновить на "Принятый"
Проигнорируйте избыточность статуса с этим примером, пожалуйста.
Теперь я предположил, что #1 - 4 можно выполнить с помощью простого "выбрать... для обновления", оставив AUTOCOMMIT равным false. С этими утверждениями я мог бы определить, нужно ли мне обновлять - и если да, я могу продолжить обновления. Затем, после завершения обновлений № 5-8, я зафиксировал бы и строки были бы разблокированы.
У меня проблемы с тем, чтобы заставить это работать, и я не знаю, происходит ли это из-за того, что я делаю, или мое мышление неверно.
Еще одна вещь... есть другие процессы, которые могут обновить состояние элемента, скажем, до истечения срока действия или отменено. Я надеюсь, что единственное решение моего подхода - не помещать каждое возможное условие в предложение WHERE в операторах UPDATE... это было бы нелегко обслуживать.
1 ответ
Мини-транзакция: сделать это одним запросом.
UPDATE item
LEFT JOIN posting
ON posting.item_id = item.id -- or however
LEFT JOIN request
ON request.item_id = item.id -- or however
LEFT JOIN posting_reponse
ON posting_response.item_id = item.id
SET
item.status = 'Reserved',
posting.status = 'Unavailable',
posting_reponse.status = 'Rejected',
request.status = IF(request.id = some-current-id,'Accepted','Rejected')
WHERE item.id = some-id AND item.status='Available';
... и перестаньте задавать вопросы о блокировке для чтения, вы действительно не хотите этого:P