【发布时间】:2014-05-22 09:24:54
【问题描述】:
由于某些原因,如果不同的用户同时运行这段代码,它可能会创建重复的游戏:
game = Game.find_or_create_by(
status: Game::STATUS[:waiting],
category_id: params[:category_id],
private: 0
) do |g|
is_new = true
g.user = current_user
end
我不清楚是怎么回事,但可能是因为不同的 Unicorn 进程使用不同的数据库连接,因此事务可以并行运行。
如果是这样,我需要正确的方法来避免它,也许我应该使用 Rails 事务或 Postgres 锁,但我确实需要一个使用示例。
谢谢。
【问题讨论】:
-
我相信您的问题出在 current_user 中,但首先将 find_or_create_by 更改为 create_by,因为 is_new 为 true。
-
添加和index to the database 以避免重复条目?
-
manu29.d,实际上我不能在 [status, category_id, private] 上使用 UNIQUE 索引:因为我只需要状态为 0(WAITING)时的唯一记录。对于其他状态,我可以有记录,复制这些列。
-
Hitham S. AlQadheeb,我没明白你的意思。 current_user 有什么问题,create_by 是什么?以下代码中使用
is_new,只是为了知道刚刚创建了记录。
标签: ruby-on-rails postgresql concurrency transactions