MySQL: как убедиться, что обновление всегда выполняется перед выбором?

0

Я создаю веб-приложение, которое позволяет N числу пользователей вводить данные квитанции.

Пользователям предоставляется набор отсканированных квитанций, но не более двух пользователей должны работать с одной и той же квитанцией.

т.е. пользователь A и пользователь B могут работать на квитанции-1, но пользователь C не может работать на нем (другой запрос, например, квитанция-2, должен быть назначен пользователю C).

Структура таблицы, которую я использую, похожа на следующую.

[Таблица получателей]

+------------+--------------+
|  user_id   |  receipt_id  |
+------------+--------------+
| 000000001  |  R0000000000 |
| 000000001  |  R0000000001 |
| 000000001  |  R0000000002 |
| 000000002  |  R0000000000 |
| 000000002  |  R0000000001 |
+------------+--------------+

[Таблица чеков]

+-------------+--------+
| receipt_id  | status |
+-------------+--------+
| R0000000000 |    0   |
| R0000000001 |    1   |
| R0000000002 |    0   |
| R0000000003 |    2   |
+-------------+--------+

★ статус 0: не назначен 1: назначено пользователю 2: назначено 2 пользователям

  1. выберите квитанции из таблицы квитанций, статус которых не равен "2",
  2. вставьте квитанции, полученные с шага 1 вместе с пользователем, которому назначены квитанции.
  3. обновить статус квитирования (0-> 1 или 1-> 2)

Вот как я планирую достичь вышеуказанного требования.

Проблема с этим подходом заключается в том, что может быть шанс, что select (step1) выполняется непосредственно перед выполнением обновления (шаг3). Если это произойдет, квитанции со статусом 2 могут быть выбраны и назначены другому пользователю, что не соответствует требованию.

Как я могу убедиться, что этого не происходит?

Теги:

1 ответ

2
Лучший ответ

Для всех целей используйте transactions:

START TRANSACTION
   your SQL commands
COMMIT

В транзакциях либо все ваши заявления выполняются, либо вообще не выполняются, и выполняет неявно блокировку обновленной строки, которая более эффективна, чем второй подход

Вы также можете сделать это, используя LOCK TABLE

Ещё вопросы

Сообщество Overcoder
Наверх
Меню