При реализации системы, которая создает задачи, которые должны быть решены некоторыми работниками, моя идея заключается в том, чтобы создать таблицу, которая будет иметь некоторое определение задачи наряду со статусом, например, для просмотра документа у нас будет что-то вроде reviewId, documentId, reviewerId, reviewTime
. Когда документы загружаются в систему, мы просто сохраняем documentId
вместе с сгенерированным reviewId
и оставляем reviewerId
и reviewTime
пустыми. Когда следующий рецензент приходит и начинает рецензию, мы просто устанавливаем его идентификатор и текущее время, чтобы пометить задание как «выполняемое» (я намеренно пропускаю случай, когда рецензент занимает много времени или умирает во время рецензии).
При реализации такого варианта использования, например, PostgreSQL, мы могли бы использовать UPDATE review SET reviewerId = :reviewerId, reviewTime: reviewTime WHERE reviewId = (SELECT reviewId from review WHERE reviewId is null AND reviewTime is null FOR UPDATE SKIP LOCKED LIMIT 1) RETURNING reviewId, documentId, reviewerId, reviewTime
(поэтому, в основном, обновите первую необработанную строку, используя SKIP LOCKED
, чтобы пропустить все уже обрабатываемые строки).
Но при переходе от нативного решения к JDB C и выше у меня возникают проблемы с реализацией этого:
- Spring Data JPA и Spring Data JDB C не позволяют запрос
@Modifying
возвращает что-либо кроме void
/ boolean
/ int
и заставляет нас выполнить 2 запроса в одной транзакции - один для первой ожидающей строки и второй с обновлением - одна альтернатива - использовать хранимую процедуру, но я действительно ненавижу идею хранения таких логи c, поэтому вдали от кода
- другая альтернатива - использовать постоянную очередь и все время пропускать базу данных. но это ввело дополнительные компоненты инфраструктуры, которые необходимо поддерживать и изучать. Любые предложения приветствуются.
Я что-то упустил? Возможно ли иметь все это или мы должны согласиться на несколько запросов или хранимых процедур?