gpt4 book ai didi

ruby-on-rails-3 - 如何处理删除和创建相同行的并发请求?

转载 作者:行者123 更新时间:2023-12-03 17:47:46 26 4
gpt4 key购买 nike

我有一个如下所示的表:

game_stats 表:

id | game_id | player_id | stats | (many other cols...)
----------------------
1 | 'game_abc' | 8 | 'R R A B S' | ...
2 | 'game_abc' | 9 | 'S B A S' | ...

用户批量上传给定游戏的数据,同时提交两个玩家的数据。例如:
"game": {
id: 'game_abc',
player_stats: {
8: {
stats: 'R R A B S'
},
9: {
stats: 'S B A S'
}
}
}

将此提交给我的服务器应该会生成第一个表。

我在 Controller 中所做的不是在再次提交相同数据时更新现有行(例如,带有修订),而是首先删除 game_stats 中的所有现有行。具有给定 game_id 的表:
class GameStatController
def update
GameStat.where("game_id = ?", game_id).destroy_all
params[:game][:player_stats].each do |stats|
game_stat.save
end
end
end

这适用于单线程或单进程服务器。问题是我正在运行 Unicorn,它是一个多进程服务器。如果两个请求同时进入,我会得到一个竞争条件:
Request 1: GameStat.where(...).destroy_all
Request 2: GameStat.where(...).destroy_all
Request 1: Save new game_stats
Request 2: Save new game_stats

结果:具有相同数据的多个 game_stat 行。

我相信以某种方式锁定行或表是防止同时进行多次更新的方法 - 但我不知道该怎么做。结合交易似乎是正确的做法,但我真的不明白为什么。

编辑

澄清为什么我无法弄清楚如何使用锁定:我不能一次锁定一行,因为该行只是被删除而不是修改。

最佳答案

AR 默认不支持表级锁定。您必须执行特定于数据库的 SQL 或使用像 Monogamy 这样的 gem。

如果没有别的,在事务中包装保存语句将加快处理速度。

另一种选择是使用 Redis 实现锁。 gem 类 redis-lock也可用。这可能会降低风险,因为它不会触及数据库,并且您可以将 Redis 键设置为过期。

关于ruby-on-rails-3 - 如何处理删除和创建相同行的并发请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29811634/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com