我有一个售票机。
效率不高。响应时间为3300毫秒。
以前使用自动收报机(counter.increment!)实现了这一问题,这会带来处理并发的问题。
目前它是作为array.shift实现的。
ticket_roll = [1, 2, 3, 4, 5]
ticket = ticket_roll.shift
任何用户都可以抢票。 第一个击中阵列的人获得了门票。
控制器
def create
@movie = Movie.find_by(movie: params[:movie])
ticket_roll = TicketRoll.find(1).ticket_roll
@ticket = ticket_roll.shift
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:card => params[:stripeToken],
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => 1500,
)
if charge["paid"]
@movie.update_attributes(status: "sold", email: params[:stripeEmail],
first_name: params[:first_name], last_name: params[:last_name])
Pusher['the_channel'].trigger('the_event', {message: ticket_roll[0]})
else
ticket_roll.unshift(@ticket)
end
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to charges_path
end
我可以将ticket_roll数组存储在内存/缓存中,以便每个用户都不会=完整的数据库查询吗?
答案 0 :(得分:1)
正如您已经提到的那样,内存中的所有票证都是低效的,并且只使用increment!
会导致并发问题。一个基本的解决方案是在更新记录时使用locks。
指南中的一个例子:
Item.transaction do
i = Item.lock.first
i.name = 'Jones'
i.save
end
在您的情况下,您只需要在DB中拥有最新票证的数量。在给出新的票号之前,您应该锁定记录,增加值并释放锁定。