I have an API endpoint in my Laravel application that should conduct an insert if a row with colum order_id
does not exists, otherwise a sequence of updates should take place (Simply calling INSERT (..) UPDATE ON DUPLICATE ..
does not work here, its a big transaction that takes place on multiple tables).
Currently, the logic goes like this where order_id
is a unique column in the database:
public function updateOrCreate(Request $request) {
try{
DB::beginTransaction();
$tempOrder = TempOrder::create(['order_id' => $request->order_id]);
TempOrder::where('order_id', '=', $order_id)->lockForUpdate()->get();
$this->createRelations($tempOrder);
DB::commit();
}
catch(\ExceoptionDuplicateRow $e)
{
DB::rollback();
$this->update($request->order_id);
}
}
public function update($order_id)
\DB::transaction(function() {
TempOrder::where('order_id', '=', $order_id)->lockForUpdate()->get();
// Do update
}
}
The problem is, its theoretically possible that if two concurrent calls take place with the same order_id
, first an TempOrder may be created but the lock may be triggered first by the call that executes the update, meaning $this->createRelations($tempOrder);
will be called after $this->update($request->order_id);
.
I have to ensure that this never happens. Is this possible? Something like
TempOrder::create(['order_id' => $request->order_id])->lockForUpdate();
?
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire