竞争条件 - 使用一个数据库的多个应用程序实

时间:2016-06-25 21:43:40

标签: ruby-on-rails postgresql scaling race-condition horizontal-scaling

我计划将我的Rails应用程序扩展到多个实例,但它们仍将使用相同的数据库。如果两个用户最终使用了两个不同的应用程序实例,编辑同一个帐户,那么肯定会在某处导致竞争条件 - 鉴于这是一个Rails应用程序,防止这种情况的最佳方法是什么?

我所知道的唯一与数据库相关的设置允许指定实际的服务器IP。如果一个程序可能是一个中间人,它会以某种方式解决问题......否则,应用程序实例必须以某种方式相互通信?

除非有办法使用Postgres中的设置来解决这个问题......

任何帮助将不胜感激!谢谢!

1 个答案:

答案 0 :(得分:0)

我建议实施 optimistic locking 策略。 Rails支持开箱即用。为此编写一个完整的教程超出了stackoverflow答案的范围。请在线查找详细说明。

基础知识是: 对于要保护的每个模型,您需要将一个名为 lock_version 的整数列添加到模型的数据库表中。此外,在每种形式中,您都需要添加一个带有此lock_version的隐藏字段。当然,如果使用安全参数,则允许控制器中的lock_version参数。

每当您保存记录并且存在lock_version时,Rails将确保lock_version与数据库中的一个匹配。如果它们不匹配,则意味着在此期间发生了另一次更新,并且当前更新失败并显示StaleObjectError

作为后备策略,我建议您向更新被拒绝的用户显示Flash消息。此外,使用数据库中的当前值(而不是尝试的输入)呈现他们再次填写的相同表单,因为您希望用户重新考虑他们的更改是否合适。

(您可以通过在rescue_from中定义ApplicationController挂钩来实施应用回退策略。)

HTH!