2017-08-30 59 views
0

修改數據在數據庫,假設當汽車被出售,它會設置IsSold = true,記錄買家,使用讀鎖檢查時/在程序

,並知道如果車已經賣了,我用的是如果檢查:

var car = GetCarFromDb().Where(car=>car.Id=2); 
if(!car.IsSold){ 
    car.IsSold = true; car.Buyer = thisUserName; 
    DbSaveChanges(); 
} 

現在有是兩個用戶做買入動作幾乎在同一時間,

和我想象下面的情況可能發生:

enter image description here

即車將被賣出兩次,這是一個問題。


是它可能使用與MSSQL C#時,會發生什麼?

如果可能的話,我想阻止它就像整個代碼塊中給汽車的數據讀鎖定和寫鎖定的唯一途徑:

GiveCarId2ReadLockWriteLock(); 
var car = GetCarFromDb().Where(car=>car.Id=2); 
if(!car.IsSold){ 
    car.IsSold = true; car.Buyer = thisUserName; 
    DbSaveChanges(); 
} 
ReleaseCarId2ReadLockWriteLock(); 

因此,如果用戶1開始檢查汽車銷售, user2必須等到user1完成售車設置,那麼user2將總是得到IsSold = true,即一輛車不會反覆出售給2個用戶。

如果是對的,那麼如何練習GiveCarId2ReadLockWriteLock();

或者有其他方法可以防止2個用戶購買同一輛車,當2個用戶差不多同時在不同的計算機/客戶端上發送購買請求嗎?

也許類似MVC,或使用存儲庫模式,或做一些特殊的技能來處理WebAPI中的一次請求,以便每個請求可以在前一個請求結束時進入onlty?

更新201710:

下面是一個Article in Entity Framework討論。

+0

您使用的是ORM,如實體框架還是直接數據庫連接? –

+0

實體框架沒問題。我suddnely想如果使用Entiyframework,也許我可以使用控制器的力量來處理一個請求一次,直到請求結束然後第二個請求可以進來,雖然我不知道練習細節 –

+0

這個應用程序的網頁或桌面? –

回答

2

嘗試通過數據庫或應用程序創建讀取鎖 - 可以工作,但解決方案會很麻煩&可能會影響大多數事務的性能,而這些事務會超出您所擔心的情況。

我會建議讓你的數據庫通過約束來做到這一點,但是規範你的數據庫模式。

代替具有1 Cars表列:

CarIdIsSoldBuyerOtherCarStuff

有2個表:

Cars具有:

CarIdOtherCarStuff

CarSales有:

CarIdBuyerSalesDate

CarId將是對兩個表的主鍵(給出的信息,我有)

然後當你嘗試寫信給該車的CarSales表&已經售出,您將獲得一個違反主要關鍵的&知道它已售出。

+0

感謝您的回答,我認爲這是可行的。 –

+0

很酷。以這種方式規範你的數據庫將爲你今後的維護和增加功能提供更多的靈活性。 –