Возможно ли, чтобы транзакции базы данных охватывали несколько запросов в рельсах? - PullRequest
9 голосов
/ 31 марта 2009

У меня есть форма, которая занимает несколько страниц. Способ его настройки сейчас не идеален, потому что он сохраняет (в базу данных) каждую страницу при ее отправке. Поэтому, если пользователь не заполняет форму на всех страницах, в базе данных будет сохранена неполная регистрация пользователя.

Я бы хотел «откатить» сохранения, если пользователь не полностью заполнил форму.

Так есть ли способ настроить транзакцию, которая начиналась бы, когда пользователь заполняет первую форму, и заканчивалась, когда пользователь заканчивал на последней странице?

Ответы [ 5 ]

5 голосов
/ 31 марта 2009

То, что вы ищете, это act_as_state_machine gem . Если вы не знакомы с государственными машинами, посмотрите здесь .

2 голосов
/ 31 марта 2009

Чтобы ответить на конкретный вопрос, я не думаю, что есть какой-либо способ настроить транзакцию в том смысле, что база данных будет делать то, что вы хотите. Подумайте об этом, и вы поймете, почему: нет никакой гарантии, что различные части вашей многостраничной операции будут обрабатываться одним и тем же процессом. Или, скорее всего, даже тот же сервер. Если запрос охватывает соединения с базой данных, как и в этой ситуации, незафиксированные части одного соединения будут невидимы для других соединений.

Помимо уже упомянутых идей, я хотел бы рассмотреть возможность использования одной или нескольких промежуточных таблиц для хранения уже введенных неполных данных. Затем, когда пользователь закончил, одна транзакция может применить данные к постоянным таблицам и удалить промежуточные данные. Неполные данные могут быть очищены по критерию возраста с помощью фонового процесса, если вы уверены, что сеанс был прекращен или удерживается до возвращения пользователя, если это лучше соответствует вашим требованиям.

Я бы склонялся к этому подходу, особенно если бы ожидал регулярных незавершенных транзакций, потому что таким образом мне не придется иметь дело с неполными данными в моих основных моделях.

1 голос
/ 31 марта 2009

Открытие транзакции базы данных, которая будет охватывать несколько запросов, является плохой идеей. Рассмотрим ситуацию, когда пользователь просто закрывает браузер до совершения транзакции. Вы остались с осиротевшей транзакцией, которая не была ни отменена, ни зафиксирована.

Просто поместите в базу данных что-то вроде REG_COMPLETE, которое устанавливается только на последней странице процесса регистрации. Затем вы можете отфильтровать / очистить / что угодно с этой неполной записью ... может быть, отправить им письмо с предложением закончить?

1 голос
/ 31 марта 2009

Я думаю, что есть смысл в сохранении каждой страницы, потому что, если это длительный процесс и пользователь прерывается посередине, они могут захотеть сохранить свои промежуточные, незафиксированные результаты и выбрать, где они остановились позже.

Если вы считаете, что это тоже хорошая идея, тогда ваш дизайн будет хранить флаг, чтобы указать, была ли конкретная часть частью длительной транзакции, которая еще не была завершена. Установите флаг, когда последний фрагмент был сделан, и кнопка сохранения была нажата. Укажите значение тайм-аута, которое сообщит, если промежуточным частям будет дано окончательное подтверждение после определенного периода времени, когда они будут удалены.

1 голос
/ 31 марта 2009

Я не знаю ответа на ваш оригинальный вопрос, но в любом случае ...

Вместо сохранения на каждой странице, почему бы не сохранить все данные в переменной сеанса? Тогда в конце вы можете иметь одну страницу, которая сохраняет данные в сеансе вниз в базу данных? Таким образом, вы никогда ничего частично не сохраняли в БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...