У меня есть следующая таблица:
case class Project(id: Int, name: String, locked: Boolean)
Пользователи могут запросить некоторую обработку для проекта - но я хотел бы убедиться, что выполняется только одно задание на обработкузапускать проект за раз.
Мой способ прямо сейчас - установить locked = true
для проекта всякий раз, когда задание начинается, и если пользователь (злонамеренный или другой) пытается запустить второе задание, пока locked = true
, он должен проверить, является ли locked
уже верным, и если это так, он должен ответить сообщением об ошибке «Пожалуйста, подождите» или что-то подобное.
Я думаю, что мне нужно сделать это с помощью транзакций, поэтому гонкиусловия / параллельные запросы не будут работать, и злонамеренный пользователь не сможет отправить одновременные запросы и запустить несколько заданий, потому что все увидели locked = false
(как они запускались одновременно)
Как я могу это сделатьс сликом?Моя текущая попытка выглядит следующим образом:
def lock(id: Long): Future[Int] = {
val select = (for {p <- projects if p.id === id && p.locked === false} yield l.locked)
val q = select.update(true).transactionally //attempting to use transactions
db.run(q)
}
Я полагаю, db.run
вернет количество обновленных строк, а если условие p.locked === false
не выполнится, то количество обновленных строк будет равно 0, иЯ мог бы использовать это, чтобы определить, был ли проект успешно заблокирован.И, возможно, .transactionally
должен выполнять этот запуск в транзакциях, чтобы одновременные запросы не были проблемой.
Верны ли мои предположения / рассуждения здесь?Есть ли лучший способ сделать это?