zoukankan      html  css  js  c++  java
  • 3.4 创建模型-并发标记

    并发标记

    并发控制概念:

    指的是用于在发生并发更改时确保数据一致性的特定机制。

    配置为并发标记的属性用于实现乐观并发控制,并发标记的实现是通过EF Core来实现并发冲突的解决,而非在数据库层面的方案。EF Core 实现了乐观并发控制(非数据库层面),这意味着它将允许多个进程或用户独立进行更改,而不会产生同步或锁定的开销。 在理想情况下,这些更改将不会相互干扰,因此都能够成功。 在最坏的情况下,两个或更多进程将尝试进行冲突更改,而其中只有一个进程会成功。

    并发控制在 EF Core 中的工作原理:

    配置为并发标记的属性用于实现乐观并发控制:每当在 SaveChanges 期间执行更新或删除操作时,会将数据库上的并发标记属性值与通过 EF Core 读取的原始值进行比较:

    (1) 如果这些值匹配,则可以完成该操作。

    (2) 如果这些值不匹配,EF Core 会假设另一个用户已执行冲突操作,并中止当前事务。这种情况被称为"并发冲突"。

    当配置好并发标记后,数据库提供程序负责实现并发标记值的比较,EF Core会对任何 UPDATE 或 DELETE 语句的WHERE 子句中的并发标记值进行检查。执行这些语句后,EF Core会读取受影响的行数。如果未影响任何行,将检测到并发冲突,并且EF Core 会引发DbUpdateConcurrencyException。

    例如,将 Person 的 LastName 配置为并发标记。 这样,对Person的任何更新操作(并发标记的属性必须作为比较参照来反映并发冲突),都将在 WHERE 子句中做并发检查,在数据库端将执行如下sql命令,条件LastName 是EF自动加上去:

    UPDATE [Person] SET [FirstName] = @p1 WHERE [PersonId] = @p0 AND [LastName] = @p2;

    并发标记后会有三组值可用于帮助解决并发冲突:
    1.“当前值”是应用程序尝试写入数据库的值。
    2.“原始值”是在进行任何编辑之前最初从数据库中检索的值。
    3.“数据库值”是当前存储在数据库中的值。

    产生并发冲突的常规处理步骤是:
    1.在 SaveChanges 期间捕获 DbUpdateConcurrencyException。
    2.使用 DbUpdateConcurrencyException.Entries 为受影响的实体准备一组新更改。
    3.刷新并发标记的原始值以反映数据库中的当前值。
    4.重试该过程,直到不发生任何冲突。

    下面使用数据注释方法将LastName属性配置为并发标记

    //注解模式
    public class Person
    {
        public int PersonId { get; set; }
    
        [ConcurrencyCheck]
        public string LastName { get; set; }
    
        public string FirstName { get; set; }
    }
    
    //API模式
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .Property(p => p.LastName)
            .IsConcurrencyToken();
    }
    

    Timestamp/rowversion

    public class Blog
    {
        public int BlogId { get; set; }
    
        public string Url { get; set; }
    
        [Timestamp]
        public byte[] Timestamp { get; set; }
    }
    
    class MyContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Blog>()
                .Property(p => p.Timestamp)
                .IsRowVersion();
        }
    }
    
  • 相关阅读:
    雷林鹏分享:CSS 链接
    雷林鹏分享:CSS 字体
    雷林鹏分享:CSS 文本格式
    转载:64,32位编程问题
    NSTimer 线程操作
    安装推送
    短信在没有网络情况下崩溃
    使用Html来避免写复杂的app代码,跨平台
    ios推送
    APN 推送
  • 原文地址:https://www.cnblogs.com/maanshancss/p/13360468.html
Copyright © 2011-2022 走看看