• Net6 EfCore CodeFirst 乐观锁 RowRersion


    十年河东,十年河西,莫欺少年穷

    学无止境,精益求精

    1、新建带有RowRersion的实体

        /// <summary>
        ///房子 -- 用于演示抢房子
        /// </summary>
        public class House
        {
            public string HouseId { get; set; }
            public string HouseName { get; set; }
            public string Onwer { get; set; }
            public int HouseCount { get; set; } 
            public DateTime? CreateTime { get; set; }
            public byte[] RowRersion { get; set; }
        }

    2、配置乐观锁令牌,并加入DbSet

        public class HouseConfig : IEntityTypeConfiguration<House>
        {
            public void Configure(EntityTypeBuilder<House> builder)
            {
                builder.ToTable("T_House"); //表名
                builder.HasKey(A => A.HouseId);//主键
                builder.Property(A => A.HouseId).HasMaxLength(50); 
                builder.Property(A => A.RowRersion).IsRowVersion();//乐观锁令牌 
            }
        }
    
    
        public class wechatDbContext : DbContext
        {
            public DbSet<House> Houses { get; set; }
           protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            {
                base.OnConfiguring(optionsBuilder);//;MultipleActiveResultSets=true
                optionsBuilder.UseSqlServer("Data Source=LAPTOP-84R6S0FB;Initial Catalog=demo1;Integrated Security=True;MultipleActiveResultSets=true");
    
            }
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
                //从当前程序集命名空间加载所有的IEntityTypeConfiguration
                modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
            }
        }

    3、通过指令更新数据库 并在数据库插入测试数据

    Add-Migration initHouse
    
    update-database

    插入数据

      insert into [demo1].[dbo].[T_House]([HouseId],[Onwer],[HouseCount],[CreateTime]) values(newid(),'河南建业',10,getdate())

    4、书写测试代码

    using Microsoft.EntityFrameworkCore;
    using System;
    using System.Collections.Generic;
    using System.Data.Common;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace EfCore
    {
        internal class Program
        {
           static int hourseCount = 0;
            static void Main(string[] args)
            {
                for (int i = 1; i < 101; i++)
                {
                    Task.Run(() => { GetHouse(); });
                }
                Thread.Sleep(20000);//20秒执行时间
                                    //
                Console.WriteLine($"总共{hourseCount}人抢房成功");
                Console.Read();
            }
    
            static void GetHouse()
            {
                using (wechatDbContext context = new wechatDbContext())
                {
                    var house = context.Houses.FirstOrDefault(A => A.Onwer == "河南建业");
                    if (house.HouseCount > 0)
                    {
                        house.HouseCount = house.HouseCount - 1;
                        try
                        {
                            context.SaveChanges();
                            hourseCount++;
                        }
                        catch (DbUpdateConcurrencyException ex)
                        {
                            //Console.WriteLine("数据库访问并发冲突");
                            //var entity = ex.Entries.FirstOrDefault();
                            //string newValue = entity.GetDatabaseValues().GetValue<string>("Onwer");
                            //Console.WriteLine($"您没能抢到该房子,房子已被{newValue}抢走");
    
                        }
                    } 
                   
                }
            }
    
        }
    }

    通过 DbUpdateConcurrencyException Laura捕获数据库并发异常

    通过异步模仿并发抢房场景

    5、测试如下

    如果不加乐观锁,脏读误读的情况下,有可能会出现10人以上抢房成功,在此就不做演示了。

    @天才卧龙的伯克利

  • 相关阅读:
    .Net Core微服务——Ocelot(2):集成Consul 老马
    .NET 微服务——CI/CD(1):Jenkins+Gitee自动构建 老马
    .Net Core——用SignalR撸个游戏 老马
    JUC之线程间的通信
    SpringBoot文章合集
    JUC之线程间定制化通信
    JUC之集合中的线程安全问题
    JUC文章合集
    JUC之Lock接口以及Synchronized回顾
    JUC概述
  • 原文地址:https://www.cnblogs.com/chenwolong/p/rowrev.html
Copyright © 2020-2023  润新知