Я создаю веб-приложение, которое позволяет 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 пользователям
Вот как я планирую достичь вышеуказанного требования.
Проблема с этим подходом заключается в том, что может быть шанс, что select (step1) выполняется непосредственно перед выполнением обновления (шаг3). Если это произойдет, квитанции со статусом 2 могут быть выбраны и назначены другому пользователю, что не соответствует требованию.
Как я могу убедиться, что этого не происходит?
Для всех целей используйте transactions
:
START TRANSACTION
your SQL commands
COMMIT
В транзакциях либо все ваши заявления выполняются, либо вообще не выполняются, и выполняет неявно блокировку обновленной строки, которая более эффективна, чем второй подход
Вы также можете сделать это, используя LOCK TABLE