我有兩筆交易。首先,我選擇一個物體,進行驗證,將客戶端檔案提供的上傳到 S3,然后使用有關 S3 檔案的資訊更新該物體。第二個事務只是洗掉這個物體。現在,假設有人呼叫了第一個事務,然后立即呼叫了第二個事務。第二個將進行得更快,第一個將 throw DbUpdateConcurrencyException,因為所選物體在更新查詢中不再存在。
我明白了DbUpdateConcurrencyException,當我的交易有IsolationLevel.ReadCommited。但是如果我設定IsolationLevel.Serializable它會拋出InvalidOperationException40001 postgres 代碼。有人可以解釋為什么我會收到不同的錯誤,因為在我看來結果應該是相同的,因為這兩個錯誤都是通過更新不存在的物體來呼叫的?
uj5u.com熱心網友回復:
該40001錯誤對應于 SQLSTATE serialization_failure(請參閱錯誤代碼表)。
它是由可串行化隔離級別的資料庫引擎在檢測到并發事務時生成的,并且該事務可能產生了如果并發事務串行運行則無法獲得的結果。使用 時 IsolationLevel.ReadCommited,不可能獲得此錯誤,因為選擇此隔離級別恰好意味著客戶端不希望資料庫執行這些隔離檢查。
另一方面,DbUpdateConcurrencyException可能不是由資料庫引擎生成的。它由物體框架生成。資料庫本身可以使用 UPDATE 更新零行,這不是 SQL 級別的錯誤。
我認為如果資料庫首先出錯,你會得到序列化失敗,如果資料庫沒有出錯,則會出現 DbUpdateConcurrencyException 錯誤,但是按分層順序(EF)的第二層會出錯。
在可序列化隔離級別,處理序列化失敗的典型方法是讓客戶端在遇到40001錯誤時重試事務。重試的事務將擁有全新的資料視圖,并有望通過(否則,重試回圈)。
在較低的隔離級別處理并發的典型方法是Read Committed在訪問物件之前顯式鎖定物件以強制并發事務的序列化。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/331692.html
標籤:PostgreSQL 例外 并发 实体框架核心
