Php 增量、减量以及Model::Decrement()和Model::Increment()在Laravel中工作不正常
我有一个奇怪的问题。我通过POST方法从API接收数据。当请求到达预定的路由时,我从请求中获取数据,然后根据请求类型减少或增加用户余额 我们有两种请求类型:贷记和借记。对于借方,我减少用户余额;对于贷方,我增加用户余额,增加请求中的金额 现在的问题是,这对几乎99%的请求有效,但对于某些请求,尽管收到了请求,但余额并没有减少 下图是我正在谈论的一个例子。带绿色边框的记录是按要求工作的记录,其金额按要求递减。带红色边框的那一个是它没有减少的地方,即使它记录了数量。下面是我用来做这件事的代码 请帮助我知道问题可能在我的代码中的什么地方,或者如何做,以便结果一致。我使用的是正常的减量和增量运算符,但它的工作方式是相同的。我决定试试laravelPhp 增量、减量以及Model::Decrement()和Model::Increment()在Laravel中工作不正常,php,laravel,Php,Laravel,我有一个奇怪的问题。我通过POST方法从API接收数据。当请求到达预定的路由时,我从请求中获取数据,然后根据请求类型减少或增加用户余额 我们有两种请求类型:贷记和借记。对于借方,我减少用户余额;对于贷方,我增加用户余额,增加请求中的金额 现在的问题是,这对几乎99%的请求有效,但对于某些请求,尽管收到了请求,但余额并没有减少 下图是我正在谈论的一个例子。带绿色边框的记录是按要求工作的记录,其金额按要求递减。带红色边框的那一个是它没有减少的地方,即使它记录了数量。下面是我用来做这件事的代码 请帮助
Model::decrement()
和Model::increment()
但是我遇到了同样的错误
public function Debit(){
$data = json_decode(file_get_contents('php://input'), true);
$username = $data['Login'];
$user = User::where('username', $username)->first();
if(!$user){
$rivalaoResponse = ["d"=>["ErrorCode"=>-10,"HasErrors"=>true,"Message"=>"InvalidPlayer"]];
return response()->json($rivalaoResponse);
}
$type="debit";
$userId = $user->id;
$amount = $data['Amount'];
$gameId = $data['GameId'];
$roundId = $data['RoundId'];
$sequence = $data['Sequence'];
if($user->decrement('casino_bakiye', $amount)){
$updatedBalance= $user->refresh()->casino_bakiye;
if($sequence){
$game = XpgTransaction::where('gameId', $gameId)
->where('roundId', $roundId)
->where('sequence', $sequence)
->first();
if(!$game){
$trxn = new XpgTransaction;
$trxn->user_id = $userId;
$trxn ->request=json_encode($data);
$trxn->type =$type;
$trxn->casino_balance = (float)$updatedBalance;
$rivalaoResponse = ["d"=>["Data"=>[(float)$updatedBalance],"ErrorCode"=>0,"HasErrors"=>false,"Message"=>""]];
try {
return response()->json($rivalaoResponse);
} finally {
$trxn->save();
}
}
$rivalaoResponse = ["d"=>["ErrorCode"=>-20,"HasErrors"=>true,"Message"=>"Duplicate transaction"]];
return response()->json($rivalaoResponse);
}
}
}
嗯,您正在经历所谓的
竞争条件
这是一种您同时执行各种事务和更新不同表的条件。这样做时,某些事务可能会先于其他事务运行,从而导致问题。要解决此问题,可以做两件事,首先,使用Laravel事务
将所有操作放入事务中,然后在完成所有操作后,提交数据库。在这种情况下,我建议将事务与悲观锁定一起使用,当处理一个请求时,您锁定表,这样就不会有其他请求从表中读取,等等。您可以在此处阅读有关悲观锁定的更多信息:您可以在此处找到有关Laravel事务的更多信息
:
嗯,您正在经历所谓的竞争条件
这是一种您同时执行各种事务和更新不同表的条件。这样做时,某些事务可能会先于其他事务运行,从而导致问题。要解决此问题,可以做两件事,首先,使用Laravel事务
将所有操作放入事务中,然后在完成所有操作后,提交数据库。在这种情况下,我建议将事务与悲观锁定一起使用,当处理一个请求时,您锁定表,这样就不会有其他请求从表中读取,等等。您可以在此处阅读有关悲观锁定的更多信息:您可以在此处找到有关Laravel事务的更多信息
:
我不明白这行如果($user->decrement($casino_bakiye',$amount))
也就是说如果用户余额递减,那么代码将运行@staI我不明白这行如果($user->decrement($casino_bakiye',$amount))
也就是说如果用户余额递减,那么代码将运行@sta
...
DB::beginTransaction();
$user = User::where('username', $username)->sharedLock()->first();
...
$game = XpgTransaction::where('gameId', $gameId)
->where('roundId', $roundId)
->where('sequence', $sequence)
->sharedLock()->first();
...
$trxn->save();
DB::commit()