2015-02-03 5 views
0

3 пользователей в системе одновременно нажмите купить билетArray.pop состояние гонки

модель

class TicketInventory < ActiveRecord::Base 
    serialize :ticket_roll, Array 
end 

ticket_roll засевают в диапазоне чисел

контроллер

ticket_inventory = TicketInventory.find(1) 
ticket_roll = ticket_inventory.ticket_roll 
TicketInventory.transaction do 
    @ticket = ticket_roll.pop 
    ticket_inventory.save 
end 

Все они получают один и тот же билет.

Я рассматривал lock_version, но это привело бы к ошибке вместо того, чтобы предоставить следующий билет.

Я также посмотрел Индексы, но для каждого билета потребовалась бы строка.

Как избежать этого состояния гонки?

+0

Что такое 'TicketInventory', как оно определено. Пожалуйста, покажите весь код действия. – BroiSatse

+0

@BroiSatse see edit please – softcode

+0

Еще нужно больше кода. Что такое ticket_roll? – BroiSatse

ответ

2

Вы пытались использовать ActiveRecord::Locking::Pessimistic. Он использует транзакцию и блокировку базы данных. Она поддерживается PostgreSQL и MySQL в соответствии с документацией:

MySQL: http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html 
PostgreSQL: http://www.postgresql.org/docs/current/interactive/sql-select.html#SQL-FOR-UPDATE-SHARE 

Вы можете использовать его таким образом:

ticket_inventory = TicketInventory.find(1) 
ticket_inventory.with_lock do 
    ticket_roll = ticket_inventory.ticket_roll 
    @ticket = ticket_roll.pop 
    ticket_inventory.save 
end 

Попробуйте, это, вероятно, может работать.

+0

Собирался написать это – softcode

Смежные вопросы