#sql #postgresql #transactions #deadlock
Вопрос:
У меня есть users
таблица и tasks
таблица со user_id
столбцом. Существует требование, чтобы у пользователя была только одна задача в active
статусе.
В основном у пользователя может быть много задач со todo
done
статусом , но только одна задача со active
статусом.
Вопрос в том, как обновить статус задачи, чтобы сохранить только одну активную задачу для пользователя. (Возможная ситуация, когда для разных задач и одного и того же пользователя будут выполняться 2 одновременные операции обновления) Мои мысли:
- начать транзакцию
- заблокируйте таблицу задач для обновления и вставки
- проверьте, есть ли у пользователя активная задача
- если не обновить статус задачи
- таблица разблокировки
- фиксация транзакции
Является ли это правильным подходом?
Комментарии:
1. вам было бы лучше отправить код….
2. какую базу данных вы используете
3. @GeorgeJoseph, postgres
Ответ №1:
Лучшим вариантом блокировки было бы определить условный уникальный индекс.
Вы создаете записи индекса в идентификаторе пользователя, когда статус=Активен
create index idx_userid on users(user_id)
where status='Active
Вот простой пример
https://dbfiddle.uk/?rdbms=postgres_10amp;fiddle=0df9c557f4e8ef659f02172b367d0ada
Комментарии:
1. Наличие ограничений гарантирует, что ваша модель будет соответствовать многопользовательским сценариям
2. Sql Server имеет что-то похожее, хотя и выглядит немного по-другому, но я не помню, чтобы MySQL поддерживал это-по крайней мере, с точки зрения частичного индекса (я мог ошибаться на этот счет). Кроме того, я добавляю кое-что о готовности к обработке ошибок при ВСТАВКЕ/ОБНОВЛЕНИИ в клиентском коде.