Я все еще запутался в блокировке строк таблицы. Я использую 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 … это было бы нелегко обслуживать.
Мини-транзакция: сделать это одним запросом.
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
Других решений пока нет …