是否可以让数据库事务跨越多个请求?

时间:2009-03-30 22:13:36

标签: ruby-on-rails ruby transactions

我有一个跨越多个页面的表单。现在设置的方式并不理想,因为它在提交时会保存(到数据库)每个页面。因此,如果用户未在所有页面上填写表单,则会在数据库中保存不完整的用户注册。

如果用户没有完全填写表单,我想“回滚”保存。

那么有没有办法设置一个事务,当用户填写第一个表单时开始,当用户在最后一页完成时结束?

5 个答案:

答案 0 :(得分:5)

您正在寻找的是acts_as_state_machine gem。如果您不熟悉状态机,请查看here

答案 1 :(得分:2)

要回答具体问题,我认为没有办法在数据库意义上建立一个能够做你想做的事情。考虑一下,你会明白为什么:不能保证多页操作的各个部分将由同一个过程处理。或者很可能甚至是同一台服务器。如果请求跨越数据库连接,就像在这种情况下一样,来自一个连接的未提交部分对其他连接是不可见的。

除了已经提到的想法之外,我还考虑使用一个或多个“临时”表来保存已经输入的不完整数据。然后,当用户完成时,单个事务可以将数据应用于永久表并删除分段数据。一旦您确信会话已被终止,或者在用户返回之前一直持有,则可以通过后台流程根据年龄标准清除不完整数据,以便更好地满足您的要求。

我倾向于这种方法,特别是如果我希望有定期的不完整交易,因为这样我就不必处理主模型中不完整的数据。

答案 2 :(得分:1)

我不知道原始问题的答案,但无论如何......

为什么不将所有数据保存在会话变量中,而不是保存在每个页面上?那么最后你可以有一个页面将会话中的数据保存到数据库中吗?这样,您就不会在数据库中部分保存任何内容。

答案 3 :(得分:1)

我认为保存每个页面是有价值的,因为如果它是一个长时间运行的过程并且用户在中间被中断,他们可能希望保存他们的中间未提交的结果,并在以后停止的地方继续。

如果您认为这也是一个好主意,那么您的设计将存储一个标志,以指示某个特定部分是否是尚未完成的长期交易的一部分。完成最后一个部分并点击保存按钮时设置标志。给出一个超时值,表示如果中间件在一段时间后被删除,则会给予“最终保存”批准。

答案 4 :(得分:1)

打开跨多个请求的数据库事务是个坏主意。考虑用户在提交事务之前关闭浏览器的情况。您将留下一个既不回滚也不提交的孤立事务。

只需在数据库中放置一个类似REG_COMPLETE的标志,只在注册过程的最后一页设置。然后你可以用不完整的记录过滤/擦洗/任何你喜欢的...也许发送一封电子邮件提示他们完成?