Блокировка на уровне строк - MySQL - для обновления

Я все еще запутался в блокировке строк таблицы. Я использую MySQL/PHP и вот мой сценарий.

У меня есть набор таблиц, которые мое приложение использует для отслеживания запросов и сообщений. Пользователь создает публикацию (таблица POSTING (P)) для элемента (таблица ITEM (I)) и может отправлять запросы отдельным пользователям (таблица REQUEST (R)) или может публиковать и получать ответы на сообщения (таблица POSTING_RESPONSE (PR))), которые будут приняты пользователем.

Пример: я пользователь с велосипедом. Я отправляю это - и также отсылаю запросы отдельным пользователям. Пользователи, которые получают запрос от меня, могут принять / отклонить / или ничего не делать. Если они принимают - это зарезервировано. Другие пользователи могут найти мои сообщения и "подать заявку" на товар. У меня есть возможность "принять" или "игнорировать" их запрос. Если я принимаю, товар зарезервирован.

Что я хочу сделать, если кто-то принимает запрос:

  1. заблокировать строку в таблице ITEM (I), соответствующую позиции

  2. заблокировать строку в таблице POSTING (P) (если строка существует), соответствующую элементу

  3. блокировка строк в таблице REQUEST (R) для любых запросов, отправленных на элемент

  4. блокировка строк в таблице POSTING_RESPONSE (PR) (если строки существуют), соответствующих элементу

  5. обновить статус пункта на "Зарезервировано"

  6. обновить статус POSTING на "Недоступно"

  7. обновить все / любые POSTING_RESPONSE до "Отклонено"

  8. обновить все ЗАПРОС на "Отклонено", кроме того, который принял - обновить на "Принятый"

Проигнорируйте избыточность статуса с этим примером, пожалуйста.

Теперь я предположил, что #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

Другие вопросы по тегам