簡體   English   中英

如何檢查條件是否正確,然后在比賽條件下插入一些東西

[英]How to check a condition if it was true then insert some thing at race condition

我們有一個api函數,它通過選擇查詢來檢查數據庫中的條件,如果確實如此,我們只想一次將一些東西插入數據庫,例如,插入完成的數據庫。 問題是,當我們多次調用此api函數並發競爭條件時,換句話說,假設我們兩次調用此函數,第一個請求檢查條件為true,然后第二個請求檢查條件為true,因此將它們插入數據庫。 但是我們想要當我們檢查條件時,沒有其他人可以再次檢查它,直到完成插入。

我們使用php / Laravel並了解一些方法,例如使用insert into ... select或使用諸如replace into ...

$order = Order::find($orderId);
$logRefer = $order->user->logrefer;
if (!is_null($logRefer) && is_null($logRefer->user_turnover_id)) {
     $userTurnover = new UserTurnover();
     $userTurnover->user_id = $logRefer->referrer_id;
     $userTurnover->order_id = $order->id;
     $userTurnover->save();

     $logRefer->order_id = $order->id;
     $logRefer->user_turnover_id = $userTurnover->id;
     $logRefer->save();
}

如果未找到logrefer則將其設置一次並進行相應的user-turnover 我們希望僅看到與此訂單相關的一個user-turnover ,但是在同時運行多次后,我們看到已插入多個user-turnover

我通常在需要順序操作時利用事務,但是我認為在您的情況下情況有點復雜,因為如果函數正在運行,則還需要有條件地評估條件。 因此,我可以為您提供的想法是,在數據庫上有一個用作信號量的變量(另一個表),該變量允許或不對表執行操作(由您設置或取消設置信號量的值所提供的條件) 。 我認為,作為優秀的程序員,信號量在許多並發函數中很有用。

即使代碼中的某些機制可以防止重復,數據庫也應該在預期唯一的列上具有唯一鍵。

將連接的查詢包裝到事務中,該事務將失敗並在競賽事件條件下回滾

try {
    DB::transaction(function() {
        $order = Order::find($orderId);
        ...
        $logRefer->save();
    });
} catch (\Illuminate\Database\QueryException $ex) {
    Log::error(“failed to write to database”);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM