簡體   English   中英

處理競爭條件

[英]Handle race condition

我正在使用ASP.NET MVC和Entity Framework(版本5)開發財務應用程序。

在我的應用程序中,用戶可以批准或拒絕交易。 如果用戶批准,將轉移資金並批准通知電子郵件,否則將發送拒絕通知電子郵件。

我關心的是 ,如果兩個用戶同時批准同一個交易。 用戶將獲得事務狀態“WaitForApprove”並進行雙重轉移(如果兩個用戶都批准)。

我如何處理這種情況 ,什么是最好的解決方案(理智和低資源消耗)。

我做了一些研究,我發現Mutex可以解決這個問題。 但我不確定這是最好的解決方案。

這是我的原始代碼看起來像(Mutex未應用)。

public void TransactionApproval(int sysTransferInfoID, string username, string command)
{
    // Get the transaction.
    var info = _transInfoRepo.GetSingle(i => i.SYS_TRANSFER_INFO_ID == sysTransferInfoID);

    if (info.SYS_TRANSFER_STATE_ID != (int)eTransferState.WaitForApprove) // Check status.
    {
        if (command == "Approve")
        {
            // Call another service to make transfer here.

            // Sent approve fund transfer notification email to other users.

            info.SYS_TRANSFER_STATE_ID = (int)eTranferState.Approved; // Change status.
            info.APPROVE_BY = username;
        }
        else if (command == "Reject")
        {
            // Sent reject fund transfer notification email to other users.

            info.SYS_TRANSFER_STATE_ID = (int)eTranferState.Rejected; // Change status.
            info.APPROVE_BY = username;
        }

        _context.SaveChanges();
    }
    else
    {
        throw new Exception("Cannot approve transaction.");
    }
}

您需要完全分離從用戶界面轉移資金的責任。 不允許用戶界面直接設置傳輸狀態。

相反,在對象上公開方法,例如ApproveTransfer()和RejectTransfer(),它們檢查對象的當前狀態,並僅在對象處於適當狀態時執行請求的操作。

該對象還需要一種機制來確保任何對象實例都知道適當的狀態,甚至是在不同的對象實例(可能在不同的服務器上)啟動所請求的操作之后創建的狀態。 為此,您必須轉到數據庫。

在數據庫中保存該狀態的最佳策略取決於您實際執行事務的方式。

如果必須在對象上設置一個標志(可能由另一個進程選取),那么具有樂觀並發性的數據庫事務就足夠了。

如果您的對象正在啟動對其他系統的調用(可能是Web服務調用以啟動傳輸),則需要鎖定數據庫中的行(具有隔離級別可重復讀取的事務)。

暫無
暫無

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

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