国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

EF Core并發(fā)控制

這篇具有很好參考價值的文章主要介紹了EF Core并發(fā)控制。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

EF Core并發(fā)控制

并發(fā)控制概念

  1. 并發(fā)控制:避免多個用戶同時操作資源造成的并發(fā)沖突問題。
  2. 最好的解決方案:非數(shù)據(jù)庫解決方案
  3. 數(shù)據(jù)庫層面的兩種策略:悲觀、樂觀

悲觀鎖

悲觀并發(fā)控制一般采用行鎖 ,表鎖等排他鎖對資源進行鎖定,確保同時只有一個使用者操作被鎖定的資源。

EF Core沒有封裝悲觀并發(fā)控制的使用,需要開發(fā)人員編寫原生SQL語句來使用悲觀并發(fā)控制。不同數(shù)據(jù)庫語法不一樣。

MySQL方案:select * from T_Houses where Id = 1 for update

如果有其他查詢操作也使用for update來查詢Id=1的這條數(shù)據(jù)的話,那些查詢就會被掛起,一直到針對這條數(shù)據(jù)的更新操作完成從而釋放這個行鎖,代碼才會繼續(xù)執(zhí)行。

代碼實現(xiàn)

根據(jù)數(shù)據(jù)庫安裝對應Nuget包,Mysql如下:

也可以使用官方的,沒什么影響

Pemelo.EntityFrameworkCore.MySql

House類

class House
{
	public long Id { get; set; }
	public string Name {get;set;}	
	public string Owner {get;set;}
}

HouseConfig類

public class HouseConfig:IEntityTypeConfiguration<House>
{
    public void Configure(EntityTypeBuilder<House> builder)
    {
        builder.ToTable("T_Houses");
        builder.Property(b => b.Name).IsRequired();
    }
}

DbContext類

public class MyDbContext:DbContext
{
     public DbSet<House> Houses { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        var connString = "server=localhost;user=root;password=root;database=ef1";
        var serverVersion = new MySqlServerVersion(new Version(5, 7, 35));
        optionsBuilder.UseMySql(connString, serverVersion);
    }
}

遷移數(shù)據(jù)庫

然后執(zhí)行數(shù)據(jù)庫遷移

安裝Nuget:Microsoft.EntityFrameworkCore.Design,Microsoft.EntityFrameworkCore.Tools

  • Add-Migration Init
  • Update-database

隨便給數(shù)據(jù)庫添加幾條信息

沒有悲觀版本

    public static void Main(string[] args)
    {
        Console.WriteLine("請輸入您的名字");
        string name = Console.ReadLine();
        using (MyDbContext db = new MyDbContext())
        {
            var h = db.Houses.Single(h => h.Id == 1);
            if (!string.IsNullOrEmpty(h.Owner))
            {
                if (h.Owner == name)
                {
                    Console.WriteLine("房子已經(jīng)被你搶到了");
                }
                else
                {
                    Console.WriteLine($"房子已經(jīng)被【{h.Owner}】占了");
                }
                return;
            }
            h.Owner = name;
            Thread.Sleep(10000);
            Console.WriteLine("恭喜你,搶到了");
            db.SaveChanges();
            Console.ReadLine();
        }
    }

EF Core并發(fā)控制

EF Core并發(fā)控制

可以看到實際上是jack搶到了,但是tom也打印了搶到!

有悲觀鎖的版本

鎖和事務是相關的,因此通過BeginTransactionAsync()創(chuàng)建一個事務,并且在所有操作完成后調(diào)用CommitAsync()提交事務

Console.WriteLine("請輸入您的名字");
string name = Console.ReadLine();
using MyDbContext db = new MyDbContext();
using (var tx = db.Database.BeginTransaction())
{
    Console.WriteLine($"{DateTime.Now}準備select from update");
    //加鎖
    var h = db.Houses.FromSqlInterpolated($"select * from T_houses where Id = 1 for update").Single();
    Console.WriteLine($"{DateTime.Now}完成select from update");
    if (!string.IsNullOrEmpty(h.Owner))
    {
        if (h.Owner == name)
        {
            Console.WriteLine("房子已經(jīng)被你搶到了");
        }
        else
        {
            Console.WriteLine($"房子已經(jīng)被【{h.Owner}】占了");
        }
        Console.ReadKey();
        return;
    }
    h.Owner = name;
    Thread.Sleep(5000);
    Console.WriteLine("恭喜你,搶到了");
    db.SaveChanges();
    Console.WriteLine($"{DateTime.Now}保存完成");
    //提交事務
    tx.Commit();
    Console.ReadKey();
}

EF Core并發(fā)控制

可以看到tom 在27:58秒的時候完成了鎖,所以程序提交的時候是tom搶到了,而不是jack,當執(zhí)行SaveChanges()之前,行的鎖會一直存在,直到Commit()事務提交之后才會釋放鎖,這時jack才會完成鎖。

EF Core并發(fā)控制

問題

  1. 悲觀并發(fā)控制的使用比較簡單。
  2. 鎖是獨占、排他的,如果系統(tǒng)并發(fā)量很大的話,會嚴重影響性能,如果使用不當?shù)脑挘踔習е滤梨i。
  3. 不同數(shù)據(jù)庫的語法不一樣。

樂觀鎖

原理

Update T_House set Owner = 新值 where Id = 1 and Owner = 舊值

當Update的時候,如果數(shù)據(jù)庫中的Owner值已經(jīng)被其他操作更新為其他值了,那么where語句的值就會為false,因此這個Update語句影響的行數(shù)就是0,EF Core就知道發(fā)生并發(fā)沖突了,因此SaveChanges()方法就會拋出DbUpdateConcurrencyException異常。

EF Core配置

  1. 把被并發(fā)修改的屬性使用IsConcurrencyToken()設置為并發(fā)令牌,

  2. public class HouseConfig:IEntityTypeConfiguration<House>
    {
        public void Configure(EntityTypeBuilder<House> builder)
        {
            builder.ToTable("T_Houses");
            builder.Property(b => b.Name).IsRequired();
            builder.Property(h => h.Owner).IsConcurrencyToken(); //這里設置列
        }
    }
    
  3. Console.WriteLine("請輸入您的名字");
    string name = Console.ReadLine();
    using (MyDbContext db = new MyDbContext())
    {
        var h = db.Houses.Single(h => h.Id == 1);
        if (!string.IsNullOrEmpty(h.Owner))
        {
            if (h.Owner == name)
            {
                Console.WriteLine("房子已經(jīng)被你搶到了");
            }
            else
            {
                Console.WriteLine($"房子已經(jīng)被【{h.Owner}】占了");
            }
    
            Console.ReadKey();
            return;
        }
        h.Owner = name;
        Thread.Sleep(5000);
        try
        {
            db.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            Console.WriteLine("并發(fā)訪問沖突");
            var entry1 = ex.Entries.First();
            string newValue = entry1.GetDatabaseValues().GetValue<string>("Owner");
            Console.WriteLine($"被{newValue}搶先了");
        }
        Console.ReadLine();
    }
    

效果截圖

EF 生成的sql語句

EF Core并發(fā)控制

EF Core并發(fā)控制

多字段RowVersion

  1. SQLServer數(shù)據(jù)庫可以用一個byte[]類型的屬性做并發(fā)令牌屬性,然后使用IsRowVersion()把這個屬性設置為RowVersion類型,這樣這個屬性對應的數(shù)據(jù)庫列就會被設置為ROWVERSION類型。對于這個類型的列,在每次插入或更新行時,數(shù)據(jù)庫會自動為這一行的ROWVERSION類型的列其生成新值。
  2. 在SQLServer中,timestamp和rowversion是同一種類型的不同別名而已。

注意這里換成SQLServer數(shù)據(jù)庫了!

實體類及配置

public class House
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string? Owner {get;set;}
    public byte[]? RowVer{get;set;}
}
//builder.Property(h => h.Owner).IsConcurrencyToken(); //刪除掉
builder.Property(h=>h.RowVer).IsRowVersion();

效果截圖

EF Core并發(fā)控制

EF Core并發(fā)控制

概念

  1. 在MySQL(某些版本)等數(shù)據(jù)庫中雖然也有類似的timestamp類型,但是由于timestamp類型的精度不夠,并不適合在高并發(fā)的系統(tǒng)。
  2. 非SQLServer中,可以將并發(fā)令牌列的值更新為Guid的值
  3. 修改其他屬性值的同時,使用h1.Rowver = Guid.NewGuid()手動更新并發(fā)令牌屬性的值。

總結(jié)

  1. 樂觀并發(fā)控制能夠避免悲觀鎖帶來的性能、死鎖等問題,因此推薦使用樂觀并發(fā)控制而不是悲觀鎖。
  2. 如果有一個確定的字段要被進行并發(fā)控制,那么使用IsConcurrencyToken()把這個字段設置為并發(fā)令牌即可。
  3. 如果無法確定一個唯一的并發(fā)令牌列,那么就可以引入一個額外的屬性設置為并發(fā)令牌,并且在每次更新數(shù)據(jù)的時候,手動更新這一列的值。如果用的是SQLServer數(shù)據(jù)庫,那么也可以采用RowVersion列,這樣就不用開發(fā)者手動來在每次更新數(shù)據(jù)的時候,手動更新并發(fā)令牌的值了。

參考鏈接

  • NuGet Gallery | Pomelo.EntityFrameworkCore.MySql 7.0.0 (https://www.nuget.org/packages/Pomelo.EntityFrameworkCore.MySql
  • 【.NET 6教程,.Net Core 2022視頻教程,楊中科主講】 https://www.bilibili.com/video/BV1pK41137He/?p=89&share_source=copy_web&vd_source=fce337a51d11a67781404c67ec0b5084

每日一道面試題

  1. 什么是裝箱和拆箱?

    答:從值類型接口轉(zhuǎn)換到引用類型裝箱。從引用類型轉(zhuǎn)換到值類型拆箱。

  2. 抽象類和接口的相同點和不同點有哪些?何時必須聲明一個類為抽象類?

    相同點:

    1. 都是用來實現(xiàn)抽象和多態(tài)的機制。
    2. 都不能被實例化,只能被繼承或?qū)崿F(xiàn)。
    3. 都可以包含抽象方法,即沒有具體實現(xiàn)的方法。
    4. 都可以被子類繼承或?qū)崿F(xiàn),并在子類中實現(xiàn)抽象方法。

    不同點:

    1. 抽象類可以包含非抽象方法,而接口只能包含抽象方法。
    2. 類只能繼承一個抽象類,但可以實現(xiàn)多個接口。
    3. 抽象類的子類可以選擇性地覆蓋父類的方法,而接口的實現(xiàn)類必須實現(xiàn)接口中定義的所有方法。
    4. 抽象類可以有構造方法,而接口不能有構造方法。、

    一個類必須聲明為抽象類的情況:

    1. 當類中存在一個或多個抽象方法時,類必須聲明為抽象類。
    2. 當類需要被繼承,但不能被實例化時,類必須聲明為抽象類。
    3. 當類中的某些方法需要在子類中實現(xiàn),而其他方法已經(jīng)有了具體實現(xiàn)時,類可以聲明為抽象類。

    總結(jié):抽象類和接口都是實現(xiàn)抽象和多態(tài)的機制,但抽象類更適合用于一些具有公共實現(xiàn)的類,而接口更適合用于定義一組相關的方法,供多個類實現(xiàn)。抽象類可以包含非抽象方法和構造方法,而接口只能包含抽象方法。文章來源地址http://www.zghlxwxcb.cn/news/detail-692286.html

到了這里,關于EF Core并發(fā)控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • EF Core入門

    EF Core入門

    EF Core是微軟官方提供的ORM框架。EF Core不僅可以操作Microsoft SQL Server、MySQL、Oracle、PostgreSQL等數(shù)據(jù)庫,而且可以操作Azure Cosmos DB等NoSQL數(shù)據(jù)庫 前提條件:已經(jīng)完整安裝了Microsoft SQL Server 下面是一個實際操作EF Core的演示 這是項目最終的目錄,這里需要關注的就是 .cs 文件 首先新

    2023年04月09日
    瀏覽(18)
  • 【EF Core】實體的主、從關系

    【EF Core】實體的主、從關系

    假設有以下兩個實體: Homework 類表示家庭作業(yè),它并不是獨立使用的,而是與學生類(Student)有依賴關系。一位學生有多個家庭作業(yè)記錄,即 Homework 對象用于記錄每位同學的作業(yè)的。按照這樣的前提,Student 是主對象,Homework 是從對象。 Student 對象有個 Homeworks 屬性,用于引

    2024年02月11日
    瀏覽(23)
  • Net Core中使用EF Core連接Mysql數(shù)據(jù)庫

    Net Core中使用EF Core連接Mysql數(shù)據(jù)庫

    Entity Framework Core的前身是微軟提供并主推的ORM框架,簡稱EF,其底層是對ADO.NET的封裝。EF支持SQLServer、MYSQL、Oracle、Sqlite等所有主流數(shù)據(jù)庫。 首先是使用時的幾個模式的整理及其理解: Code First:根據(jù)代碼自動創(chuàng)建數(shù)據(jù)庫表結(jié)構甚至是數(shù)據(jù)庫,可以支持多庫開發(fā),代碼較少冗余

    2024年01月24日
    瀏覽(28)
  • EF Core + MySQL 基本增刪改查

    EF Core + MySQL 基本增刪改查

    基于EF Core + MySQL的基本增刪改查,示例是基于.NET6 + EF Core + MySQL 創(chuàng)建實體和數(shù)據(jù)庫、EFCore 數(shù)據(jù)遷移項目基礎上的內(nèi)容增加。同時也是對基于Canal實現(xiàn)MySQL 8.0 數(shù)據(jù)庫數(shù)據(jù)同步項目的驗證。 Controllers----添加----控制器,選擇api----包含讀寫操作的API控制器。 將上下文類注入到User

    2024年02月08日
    瀏覽(23)
  • 使用EF Core創(chuàng)建webapi接口(二)

    使用EF Core創(chuàng)建webapi接口(二)

    有錯誤歡迎大家給我指正 說明:netcore webapi+net6+EF?Core版本,codefirst模式(代碼創(chuàng)建數(shù)據(jù)庫) 1.netcore webapi+net6+EF?Core版本,dbfirst模式(代碼生成數(shù)據(jù)庫)見:使用EF Core創(chuàng)建webapi接口(一)-CSDN博客 2.netcore webapi+net6+EF?Core+vue前后端聯(lián)動版本,見netcore webapi+net6+EF Core+vue3前后端聯(lián)動-CSD

    2024年02月21日
    瀏覽(25)
  • EF Core 在實際開發(fā)中,如何分層?

    EF Core 在實際開發(fā)中,如何分層?

    分層就是將 EF Core 放在單獨的項目中,其它項目如 Asp.net core webapi 項目引用它 這樣的好處是解耦和項目職責的清晰劃分,并且可以重用 EF Core 項目 但是也會數(shù)據(jù)庫遷移變得復雜起來 創(chuàng)建一個 .NET 類庫項目,項目名字為 BooksEFCore 引用以下 Nuget 包 Microsoft.EntityFrameworkCore.Relati

    2024年01月24日
    瀏覽(25)
  • EF Core預編譯模型Compiled Model

    EF Core預編譯模型Compiled Model

    最近還在和 npgsql 與 EF Core 斗爭,由于 EF Core 暫時還不支持 AOT,因此在 AOT 應用程序中使用 EF Core 時,會提示問題: 聽這個意思,似乎使用 Compiled Model 可以解決問題,于是就又研究了一下 EF Core 的這個功能。 在 EF Core 中,模型根據(jù)實體類和配置構建,默認情況下,每次創(chuàng)建

    2024年02月05日
    瀏覽(19)
  • Ef Core花里胡哨系列(4) 多租戶

    當然,我們要考慮設計問題,例如,切換 Schema 或者改變數(shù)據(jù)庫時, Ef Core 同樣也會刷新改實體的緩存,所以,首次查詢將會很慢,不適合大表。 在我的上一篇博客中 [Ef Core花里胡哨系列(3) 動態(tài)修改實體對應的表(分表)、多租戶] 中我們實現(xiàn)了如何分表,同理,我們可以用近

    2024年02月03日
    瀏覽(19)
  • EF Core實操,數(shù)據(jù)庫生成實體,遷移

    EF Core實操,數(shù)據(jù)庫生成實體,遷移

    大家好,我是行不更名,坐不改姓的宋曉剛,下面將帶領大家進入C#編程EF Core數(shù)據(jù)庫基礎入門知識,如何連接數(shù)據(jù)庫,如何編寫代碼,跟上我的步伐進入EF Core數(shù)據(jù)庫下的世界。 家人們,如果有什么不懂,可以留言,或者加我聯(lián)系方式,一起進入微軟技術的開拓。 微信:153

    2024年01月22日
    瀏覽(20)
  • ASP.NET Core Web API入門之三:使用EF Core

    ASP.NET Core Web API入門之三:使用EF Core

    一般來講我們做項目都會用實體類跟數(shù)據(jù)庫實體進行關系對應,這樣的好處方便我們維護、增刪改查,并且可以減少SQL的編寫,從而統(tǒng)一風格,那么 Entity Framework Core 就是很不錯的ORM框架。 1、跨數(shù)據(jù)庫支持能力強大,只需修改配置就可以輕松實現(xiàn)數(shù)據(jù)庫切換。 2、提升了開發(fā)效

    2024年02月10日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包