在我的应用程序中,工作人员可以在他们的帐户中建立贷方余额,并在他们认为合适的情况下将其退回到他们的银行帐户。有一个MoneyController::withdraw
动作,在current_worker
上调用.withdraw_funds
方法,该方法调用平衡支付API,如果他们要求提取的amount
为< =他们余额中的金额,则贷记他们的银行账户。创建一个Transaction
,附加到工作人员Account
,该清单列出从余额中扣除并记入他们的银行帐户的金额。(Rails)有些用户在从余额中提取钱到银行账户时获得两次付款。无法复制
最近发生了一些情况,即控制器操作受到影响并且整个过程发生两次,即使请求在余额为空时应该被拒绝。撤销发生两次,两个事务使用相同或非常接近的时间戳生成。但是,它只发生在一些工作人员身上,我无法在开发或登台服务器上重现错误。我希望有人可以给我一些关于如何进行调试的建议。下面是相关代码:
MoneyController
def withdraw
if current_worker.withdraw_funds((params[:amount].to_d*100).to_i, params[:bbank])
redirect_to worker_money_path, notice: "Successfully withdrew $#{params[:amount]}"
else
redirect_to worker_money_path, alert: "Failed to withdraw funds. Please contact us for assistance."
end
end
/
worker.rb
def withdraw_funds(amount, bbank_id)
bcust = self.get_balanced
bbank = Balanced::BankAccount.fetch("/bank_accounts/#{bbank_id}")
if bbank and (bbank.customer.id == bcust.id)
puts "bank belongs to worker"
if self.account.balance >= amount
res = bbank.credit(amount: amount)
self.account.debit(amount)
Transaction.create(amount: amount, tag: 'cashout', source_id: self.account.id, destination_id: nil, balanced_id: res.id)
return true
else
puts "worker #{self} doesn't have #{amount} in account"
return false
end
else
puts "bank does not belong to worker"
return false
end
end
如果员工的平衡包含$ 50和两个请求为50 $做,首先应该成功,那么第二个要失败,因为天平现在$ 0(因此if self.account.balance >= amount
)。
我能够通过开发服务器的日志看起来很好,找到这种情况发生时的日志:我在这两个请求具有相同的真实性令牌,但我不是日志注意到
Started POST "/money/withdraw" for 68.119.221.188 at 2014-11-05 13:56:41 -0500
Processing by MoneyController#withdraw as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x5olIpvJf2K37lYRJypIIHYNhAdZUm1ptill13w9Evw=", "amount"=>"48.50", "bbank"=>"BA2...", "commit"=>"Withdraw"}
Started POST "/money/withdraw" for xx.xxx.xxx.xxx at 2014-11-05 13:56:46 -0500
Processing by MoneyController#withdraw as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x5olIpvJf2K37lYRJypIIHYNhAdZUm1ptill13w9Evw=", "amount"=>"48.50", "bbank"=>"BA2...", "commit"=>"Withdraw"}
Redirected to http://myapp.com/money
Completed 302 Found in 4467.9ms (ActiveRecord: 54.7ms)
Started GET "/worker/money" for xx.xxx.xxx.xxx at 2014-11-05 13:56:50 -0500
Processing by Worker::MoneyController#index as HTML
Redirected to http://myapp.com/money
Completed 302 Found in 9099.1ms (ActiveRecord: 69.6ms)
当然还有什么要从他们身上带走。我认为这可能与工作人员多次单击“提款”按钮一样简单,但是我试图在开发和分期中重新创建问题,从未造成问题。请求刚刚排队,随后的请求始终引起余额为空的正确响应。
编辑我设置在生产服务器上测试场景,并能够通过点击按钮退出多次重现该问题。任何人都有任何想法,为什么这会发生在生产,但不在发展或阶段?连接速度可能与它有什么关系?
嗨。请求是由ajax还是通常由javascript启动的? – 2014-11-05 22:17:10
不,这是一个HTML请求 – sixty4bit 2014-11-05 22:22:18
您可以粘贴表单的html,如果有任何现有的相对事件处理程序(在JavaScript或jQuery中)? – 2014-11-05 22:24:25