• Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制


    通用的序列号生成器库 从SQL Server迁移到Mysql 遇到的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft SQL Server数据库中的实现。SQL Server timestamp 数据类型与时间和日期无关。SQL Server timestamp 是二进制数字,它表明数据库中数据修改发生的相对顺序。实现 timestamp 数据类型最初是为了支持 SQL Server 恢复算法。每次修改页时,都会使用当前的 @@DBTS 值对其做一次标记,然后 @@DBTS 加1。这样做足以帮助恢复过程确定页修改的相对次序,但是 timestamp 值与时间没有任何关系。 而在MySQL中,TIMESTAMP列类型提供一种类型,你可以使用它自动地用当前的日期和时间标记INSERT或UPDATE的操作。如果你有多个TIMESTAMP列,只有第一个自动更新。

    在Entity Framework 中采用IsConcurrencyToken配置后RowVersion即自动用于where子句中用于比较Row Version, 我们也需要使用这个特性实现并发控制,Ak.Ini的博文http://www.cnblogs.com/akini/archive/2013/01/30/2882767.html ,我们按照这篇文章的方法在Entity framework core上面解决并发控制问题。

    定义的序列号类型:

    [Table("DbServerSequence")]
       public  class DbServerSequence : ISequence
       {

           public DbServerSequence()
           {
              
           }
           public DbServerSequence(SequenceOptions options):this()
           {
               StartAt = options.StartAt;
               CurrentValue = StartAt;
               Increment = options.Increment;
               MaxValue = options.MaxValue;
               MinValue = options.MinValue;
               Cycle = options.Cycle;

           }

           public String Key { get; set; }
           public long StartAt { get;  set; }
           public int Increment { get;  set; }
           public long MaxValue { get;  set; }
           public long MinValue { get;  set; }
           public bool Cycle { get;  set; }
           public long CurrentValue { get; set; }

           [ConcurrencyCheck]
           public DateTime RowVersion { get; set; }

           public DateTime DateCreated { get; set; }
       }
    其中RowVersion 是用作并发控制的,针对Mysql 不允许byte[]类型上标记TimeStamp/RowVersion,这里使用DateTime类型。

    数据库表定义如下(自MySQL 5.6.5版本开始,DEFAULT CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP 选项也可以应用到Datetime类型的列):

    DROP TABLE IF EXISTS `dbserversequence`;
    CREATE TABLE `dbserversequence` (
      `Key` varchar(128) NOT NULL,
      `StartAt` bigint(20) NOT NULL,
      `Increment` int(11) NOT NULL,
      `MaxValue` bigint(20) NOT NULL,
      `MinValue` bigint(20) NOT NULL,
      `Cycle` bit(1) NOT NULL,
      `CurrentValue` bigint(20) NOT NULL,
      `RowVersion` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      `DateCreated` datetime NOT NULL,
      PRIMARY KEY (`Key`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    在 SequenceDbContext 的OnModelCreating 重写如下,主要是配置并发控制字段:

            protected override void OnModelCreating(ModelBuilder builder)
           {
               base.OnModelCreating(builder);

               builder.Entity<DbServerSequence>(e =>
               {
                   e.HasKey(x => x.Key);
                   e.Property(x => x.RowVersion).IsRowVersion().IsConcurrencyToken();
               });
           }
    这个方案同时适用各种数据库,尤其是类似MySql和Postgresql这种不支持默认RowVersion字段的数据库。 最新的代码放在https://github.com/geffzhang/Sequence/tree/dotnetcore

  • 相关阅读:
    android中自定义Theme以及TitleBar
    PaddlePaddle(飞浆)图像分割7日打卡营心得
    tensorflow中models的安装
    多个重要的多项式算法以及源码
    dll中全局变量在外部进行引用
    旋转、平移、缩放矩阵
    windows编译caffe2遇到的问题
    关于opencv中cv::Mat设置roi
    Recall(召回率);Precision(准确率);F1-Meature(综合评价指标);true positives;false positives;false negatives..
    ubuntu16.04 无法wifi链接一段时间掉线且无法再连接
  • 原文地址:https://www.cnblogs.com/shanyou/p/6241612.html
Copyright © 2020-2023  润新知