Mam tabeli, który wygląda tak:Jak obsługiwać równoczesne żądania, które usuwają i tworzą te same wiersze?
game_stats tabeli:
przesłaneid | 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' | ...
danych użytkownika dla danej gry luzem, przedstawiając dane obu graczy naraz. Na przykład:
"game": {
id: 'game_abc',
player_stats: {
8: {
stats: 'R R A B S'
},
9: {
stats: 'S B A S'
}
}
}
Przesłanie tego do mojego serwera powinno spowodować powstanie pierwszej tabeli.
Zamiast aktualizacji istniejących wierszy, gdy te same dane są ponownie składane (z wersjami, na przykład), co robię w moim kontroler jest najpierw usunąć wszystkie istniejące wiersze w tabeli game_stats
które mają daną 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
Działa to dobrze na pojedynczym lub pojedynczym serwerze procesów. Problem polega na tym, że używam Unicorn, który jest serwerem wieloprocesowym. Jeśli dwa wnioski są w tym samym czasie, pojawia się stan Rasa:
Request 1: GameStat.where(...).destroy_all
Request 2: GameStat.where(...).destroy_all
Request 1: Save new game_stats
Request 2: Save new game_stats
Wynik: Wiele wierszy game_stat z tych samych danych.
Wierzę, że blokowanie wierszy lub tabeli jest sposobem na uniknięcie wielu aktualizacji w tym samym czasie - ale nie mogę wymyślić, jak to zrobić. Połączenie z transakcją wydaje się słuszne, ale tak naprawdę nie rozumiem dlaczego.
EDIT
Aby wyjaśnić, dlaczego nie mogę dowiedzieć się, jak korzystać z blokady: Nie mogę zablokować jeden wiersz na raz, ponieważ rząd jest po prostu usunięte i nie modyfikowane.