2012-05-27 29 views
1

我對樂觀併發異常有些懷疑。實體框架和一些普遍懷疑樂觀併發異常

嗯,比如說,我從數據庫中檢索一些數據,我修改了一些寄存器,然後提交更改。如果有人更新我的請求和我的更新之間的寄存器信息,我會得到樂觀的異常。經典的併發問題。

我的第一個疑問是以下幾點。 EF決定信息是否被更改,從數據庫中檢索數據,並將我獲得的原始數據與從數據庫檢索到的數據進行比較。如果存在差異,則引發樂觀併發異常。

如果當我趕上樂觀併發異常,我決定,如果客戶端贏或商店獲勝。在這一步中,EF再次檢索信息或使用第一個檢索到的數據?因爲如果再次檢索數據,這將是低效的。

第二個疑問是如何控制的樂觀併發異常。在catch代碼塊中,我決定客戶是贏還是商店贏。如果客戶贏了,那麼我再次調用saveChanges。但在我決定客戶端獲勝和保存更改的時間之間,其他用戶可能會更改數據,因此我再次遇到樂觀併發異常。從理論上講,它可能是一個無限循環。

會是使用事務(範圍內),以確保客戶端更新數據庫中的信息是個好主意?其他解決方案可以使用循環嘗試N次來更新數據,如果不可行,請退出並將其發送給用戶。

交易是一個好主意嗎?它會消耗大量的數據庫資源嗎?儘管事務會暫時阻塞數據庫,但它確保更新操作完成。 N次循環嘗試完成操作,將數據庫調用N次,也許可能需要更多資源。

謝謝。 Daimroc。

編輯:我忘了問。是否有可能將上下文設置爲默認使用客戶端而不是等待併發異常?

回答

5

我的第一個疑問就是下面。 EF來決定信息是否被更改或不從 ,從數據庫檢索數據...

它不從數據庫中檢索任何附加數據。它會將用於併發處理的實體的原始值用於update命令的條件中。更新命令後面是選擇修改的行數。如果數字爲0,則表示該記錄不存在或有人更改過。

第二個疑問是如何控制樂觀併發異常。

您只需致電RefreshSaveChanges即可。如果需要,您可以重複幾次。如果你有很多高度併發的應用程序,多線程正在爭取在幾秒鐘內更新相同的記錄,那麼你很可能需要以不同的方式構建數據存儲。

使用事務(範圍)來確保客戶端更新數據庫中的信息是否是一個好主意?

SaveChanges總是使用數據庫事務。除非您希望通過多次調用SaveChanges,分佈式事務或更改事務的隔離級別等事務,否則TransactionScope不會爲您添加任何附加值。

是否有可能將上下文設置爲默認使用客戶端而不是 等待併發異常?

它是默認設置的。簡單地不要用ConcurrencyMode.Fixed標記任何屬性,並且您將沒有併發處理=客戶端獲勝。

+0

謝謝。我有一個STE,我沒有將任何屬性標記爲ConcurrencyMode.Fixed,但是當我創建一個新的STE時,使用MarkedAsModfied方法並更新屬性時,EF檢測到最後一次加載後STE已被修改,創建。所以我在調用savechanges時總會得到一個樂觀的併發異常。爲什麼會出現這個問題?謝謝。 –