Существует web приложение со следующим функционалом:
Пользователь может создать сущность в БД (PostgreSQL), назовем эту сущность: "модуль". К модулю затем можно обратиться по API. Пока к модулю не было ни одного обращения, он считается временным и будет удален через сутки. Как только к модулю было хоть одно обращение, он "фиксируется" и остается активным пожизненно (до удаления самим пользователем).
Есть 2 разных типа обращения к модулю и многие крупные партнеры посылают разом 2 запроса. Под "разом" я подразумеваю разницу во времени в несколько миллисекунд. Среднее время выполнения запроса - 100ms, так что эти запросы выполняются параллельно.
Суть проблемы.
Количество реальных модулей (к которым обратились хоть раз) - примерно 1% от всех созданных. Дабы не захламлять базу я пытался создавать временный модуль в redis и затем, при обращении к нему, уже переносить в БД. Данная затея провалилась, так как в случае с двумя запросами, пока один запрос выдергивал структуру модуля из redis и создавал сущность в БД, второй запрос не находил записи ни в redis (так как ее оттуда уже удалил первый запрос), ни в реальной БД (так как первый запрос еще не комитнул транзакцию).
В данный момент временный модуль создается сразу в основной БД, но мне это не нравится, так как это сейчас создается примерно по 20 тысяч модулей в сутки, а в перспективе будет по 400-500 тысяч и больше.
Вопросы.
Чем чревато ежедневное добавление и удаление большого количества строк в таблицу и можно ли на таких, относительно небольших объемах об этом не беспокоиться и начинать думать над решением, когда кол-во суточных записей приблизится к паре миллионов? Следует заметить, что из этой таблицы еще идут постоянные выборки, так что нужна хорошая скорость доступа.
Как можно грамотно решить задачу, если будет цель писать в основную БД только "живые" модули? Не хочется локать всю таблицу на время пока один запрос берет запись из редиски и переносит ее в БД, ведь это будет лок всей таблицы, а не одной записи..
P.S. Менять логику и делать 2 типа обращения через один запрос - не вариант от слова "совсем". Эта логика установлена не нами и менять ее ради нас никто не будет :)
Я бы сделал крон для очистки таблицы от сущностей, к которым не было обращения в течении установленного времени. Естесственно надо фиксировать факт обращения где-то. Сущности хранить в одной базе.
Или очередь - при создании сущьности ставить задачу в отложенную очередь, которая через сутки попадает в консьюмер и обрабатывается.
Можно удалять запись из Redis после того как она попала в PG - т.о. не будет проблемы
Данная затея провалилась, так как в случае с двумя запросами, пока один запрос выдергивал структуру модуля из redis и создавал сущность в БД, второй запрос не находил записи ни в redis (так как ее оттуда уже удалил первый запрос), ни в реальной БД (так как первый запрос еще не комитнул транзакцию).
Но есть риск неконсистентности (я не знаю сути запросов).
Еще экстремальный вариант - поменять бд, на ту, которая поддерживает автоматическое удаление, например MongoDB.