你们是怎么解决服务端重复更新的问题了
首先不考虑前端的,完全隔离
如果是单纯服务端你们是怎么解决的
public function update(RechargeRecordRequest $request, RechargeRecord $rechargeRecord): RechargeRecordResource
{
if($rechargeRecord->status != 'pending')
{
throw new InvalidRequestException("不能重复更新");
}
$user = auth()->user();
if ($request->status == 'approved')
{
$balance = $user->balance + $request->charges;
DB::beginTransaction();
try {
$this->users->updateBalance($user, $balance); // 乐观锁更新
// 写入财务日志
$user->financialRecords()->create(['type' => FinancialType::recharge, 'charges' => $request->charges, 'description' => sprintf('银行转帐', $user->phone)]);
$rechargeRecord->status = 'approved';
$rechargeRecord->auditor = $user->id;
$rechargeRecord->description = $request->description;
$rechargeRecord->note = $request->note;
$rechargeRecord->save(); //更新状态是没有采用乐观锁的,因为一旦采用乐观锁,下面还要return,如果用乐观锁就还的再刷新一次
DB::commit();
}catch (InvalidRequestException $e) {
DB::rollBack();
throw $e;
}
}elseif($request->status == 'rejected')
{
$rechargeRecord->status = 'rejected';
$rechargeRecord->auditor = $user->id;
$rechargeRecord->description = $request->description;
$rechargeRecord->note = $request->note;
$rechargeRecord->save();
}
return new RechargeRecordResource($rechargeRecord);
}
加锁
Cache::lock()
核心还是锁,数据库锁或者是文件锁,redis锁,还有就是队列,串行化更新
用 redis::setnx 来实现
并发不大,mysql 悲观锁完全可以解决,并发比较大的话,就用redis分布式锁,并发特别大,建议两者并用。不过设计的时候需要考虑死锁的问题。