Rails接受重复的POST请求

Ste*_* St 4 ruby post ruby-on-rails

我的rails应用程序有一个奇怪的问题.我的应用程序在一秒钟内接受重复的POST请求

这个重复的请求,包含相同的数据,奇怪地能够绕过我的模型的唯一性验证.这导致创建具有完全相同内容的两行数据.

令我感到困惑的是,它每天只发生一次,从昨天开始,我不确定是什么造成的.(系统已经存在,并且被我的客户使用,此方法调用每天使用200-300次,我根本无法重现)

所以这是我的代码片段的情况,并按时间顺序链接到完整的代码

  1. 用户想要创建新事务,将在控制器上调用此方法

    def new  
      @penjualan = Penjualan.new  
      @penjualan.kode_transaksi = "J"+ DateTime.now.strftime("%d%m%Y%H%M%S")+@active_user.id.to_s  
      @customers = Customer.all(:limit => cookies[:limit], :order=>:kode_kustomer )  
      @barangs = Barang.all(:limit => cookies[:limit] )  
      respond_to do |format|  
        format.html # new.html.erb  
        format.json { render json: @penjualan }  
      end     
    end  
    
    Run Code Online (Sandbox Code Playgroud)

    完整的控制器在http://pastebin.com/Lmp7hncn第648行

  2. 在"新"视图中,我已使用:disable_with禁用了该按钮,因此用户无法单击提交按钮两次,从而阻止用户启动双POST请求

    .row  
      .span4  
        = f.submit 'Proses', :class=>"btn btn-large btn-primary", :disable_with => "Processing..."
    
    Run Code Online (Sandbox Code Playgroud)

    http://pastebin.com/7b9W68RY第97行的完整视图

  3. Submitted请求将在控制器上调用'create'方法,与#1相同的控制器,此方法在1秒差异上调用两次.更奇怪的是,这个请求绕过了我在模型上定义的唯一性验证,它应该使第二个请求失败,因为第一个请求具有相同的kode_transaksi

  4. 我对我的模型(Penjualan)属性有独特的限制(kode_transaksi)

    class Penjualan < ActiveRecord::Base  
      attr_accessible :customer_id, :jatuh_tempo, :kode_transaksi, :no_sj, :tanggal_bayar, :tanggal_transaksi, :total,:total_diskon, :ongkos, :user_id, :status_pembayaran, :is_returned, :kartu_kredit, :kartu_debit  
      has_many :detil_penjualans  
      attr_accessible :cash_total, :kembali  
      belongs_to :user  
      belongs_to :customer  
    
      validates :kode_transaksi, :uniqueness =>{:message=>"Transaksi Sudah Terjadi"}  
    
      scoped_search :on => [:kode_transaksi, :tanggal_transaksi, :status_pembayaran, :tanggal_bayar, :jatuh_tempo, :total ]  
      scoped_search :in => :customer, :on => [:nama_kustomer, :kode_kustomer]  
      scoped_search :in => :user, :on => [:username]  
    end  
    
    Run Code Online (Sandbox Code Playgroud)
  5. 我的生产日志包含案例片段

    Started POST "/penjualans" for 192.168.1.104 at 2012-11-24 12:15:40 +0900   
    Processing by PenjualansController#create as HTML     
    Parameters: {.... too long, see below ....}  
    
    
    Started POST "/penjualans" for 192.168.1.104 at 2012-11-24 12:15:41 +0900   
    Processing by PenjualansController#create as HTML     
    Parameters: {..... too long, see below ....}   
    Redirected to url/penjualans/17403   
    Completed 302 Found in 378ms (ActiveRecord: 246.0ms)   
    Redirected to url/penjualans/17404   
    Completed 302 Found in 367ms (ActiveRecord: 233.8ms)
    
    Run Code Online (Sandbox Code Playgroud)

日志的片段http://pastebin.com/3tpua9gi

  1. 这种情况在我的数据库上创建了一个重复的条目,导致问题

我对这种行为感到非常困惑,我的斗智斗勇.任何帮助都感激不尽.

Tig*_*ine 6

为了快速解决问题,我建议您在模型之外向数据库添加唯一约束.

rails文档建议,唯一性验证应该伴随数据库中的唯一约束,以防止两个连接同时插入相同唯一值的问题.

除此之外,用户是否可能会快速连续双击表单?也许禁用表单无法正常工作,因此允许用户点击两次?

它是每天同时还是仅在特定时间?

  • 当作为反向代理(例如,在Thins或Unicorns之前)工作时,Nginx有时会在后端发生某些错误时重新发送请求.违反RFC 2616,它甚至会对POST和PUT请求执行此操作,这些请求绝对不会被重新分配...因此,您必须确保您的数据库约束是合理的. (4认同)