Entity Framework入門教程(13)---EF中的高並發


EF中的高並發

  這里只介紹EF6中database-first開發方案的高並發解決方案,code-first開發方案中的高並發會在以后的EF CodeFirst系列中介紹。

  EF默認支持樂觀並發:我們從數據庫加載了一條數據,這是有人修改了這條數據,而我們手中用的還是舊數據,這就出現了臟讀,這個時候我們修改了這條數據然后執行SaveChange()會發生什么呢?EF在保存數據時會首先查看數據庫中的數據有沒有改變過,數據沒有改變就執行保存;數據改變了會拋出異常,我們再次提交前必須解決沖突(提到解決沖突是不是想到了git提交中的沖突?EF中解決高並發的方法和git提交的方法采用的思想是一樣的,往下看就知道了)。

1.使用步驟

1.添加RowVersion列

  在EF中database-first開發模式中,為了解決高並發問題我們可以為數據表填加一個timestamp類型的的列,列名為rowversion,rowversion是一個二進制的數據,在每次的添加/修改操作后rowversion的值都會變大

以Student實體為例,給Student表添加一個Rowversion列,類型為timestamp,如下所示:

2.生成/升級EMD

如果沒有EDM通過數據庫生成新的實體數據模型,如果有EDM則右擊設計器->Update Model From Database ->Refresh Student table,這時我們就可以在設計器中看到RowVersion屬性了,RowVersion屬性的Concurrency Mode設置為Fixed,如下圖

做完這兩步,EF API在執行Update時,會把RowVersion添加到where子句中(就像這樣:update tb set cloName=xxx where Id=@id and RowVersion=@rowversion),如果where子句中的RowVersion值和數據庫中的不一樣就拋出DbUpdateConcurrencyException

2.一個栗子

Student student = null; 

using (var context = new SchoolDBEntities())
{
    student = context.Students.First();
}

//修改學生名字
Console.Write("Enter New Student Name:");
student.StudentName = Console.ReadLine(); //Assigns student name from console

using (var context = new SchoolDBEntities())
{
    try
    {
        context.Entry(student).State = EntityState.Modified;
        context.SaveChanges();

        Console.WriteLine("修改成功!");
    }
    catch (DbUpdateConcurrencyException ex)
    {
        Console.WriteLine("發生高並發異常!");
    }
}

假設有兩個用戶都在執行上邊的代碼,User1和User2拿到了同一個Student實例,User1打字快1秒就把這個Student的用戶修改了,並在數據庫保存成功(User1執行Update時RowVersion和數據庫一致,所以不報錯,保存完成后Student的RowVersion自動改變了),這時User2也完成了修改,在User2執行保存到數據庫時(生成的Update語句中的RowVersion和數據庫中不一致了,所以拋出異常)。

 

EF系列目錄鏈接:Entity Franmework系列教程匯總


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM