Нужно ли блокировать стол?

#sql #postgresql #transactions #deadlock

Вопрос:

У меня есть users таблица и tasks таблица со user_id столбцом. Существует требование, чтобы у пользователя была только одна задача в active статусе.

В основном у пользователя может быть много задач со todo done статусом , но только одна задача со active статусом.

Вопрос в том, как обновить статус задачи, чтобы сохранить только одну активную задачу для пользователя. (Возможная ситуация, когда для разных задач и одного и того же пользователя будут выполняться 2 одновременные операции обновления) Мои мысли:

  1. начать транзакцию
  2. заблокируйте таблицу задач для обновления и вставки
  3. проверьте, есть ли у пользователя активная задача
  4. если не обновить статус задачи
  5. таблица разблокировки
  6. фиксация транзакции

Является ли это правильным подходом?

Комментарии:

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 поддерживал это-по крайней мере, с точки зрения частичного индекса (я мог ошибаться на этот счет). Кроме того, я добавляю кое-что о готовности к обработке ошибок при ВСТАВКЕ/ОБНОВЛЕНИИ в клиентском коде.