票证分配器:内存中的数组?

时间:2015-02-03 07:29:44

标签: ruby-on-rails arrays caching memory

我有一个售票机。

效率不高。响应时间为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数组存储在内存/缓存中,以便每个用户都不会=完整的数据库查询吗?

1 个答案:

答案 0 :(得分:1)

正如您已经提到的那样,内存中的所有票证都是低效的,并且只使用increment!会导致并发问题。一个基本的解决方案是在更新记录时使用locks

指南中的一个例子:

Item.transaction do
  i = Item.lock.first
  i.name = 'Jones'
  i.save
end

在您的情况下,您只需要在DB中拥有最新票证的数量。在给出新的票号之前,您应该锁定记录,增加值并释放锁定。