专栏首页张善友的专栏Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ASP.NET MVC2 数据模型验证类库:MVC Foolproof Validation

    MVC Foolproof Validation是一个数据模型类库扩展。 操作符验证 1: public class SignUpViewModel ...

    张善友
  • c#开源消息队列中间件EQueue 教程

    一、简介 EQueue是一个参照RocketMQ实现的开源消息队列中间件,兼容Mono,具体可以参看作者的文章《分享一个c#写的开源分布式消息队列equeue》...

    张善友
  • Web服务和Microsoft平台

    Microsoft 对 Web 服务的支持 Web 服务自出现之日起即构成了 Microsoft 在互操作性方面努力的基础。除使用 .NET 来围绕 Web 服...

    张善友
  • Linux内存寻址之分段机制及分页机制【转】

    本文涉及的硬件平台是X86,如果是其他平台的话,如ARM,是会使用到MMU,但是没有使用到分段机制; 最近在学习Linux内核,读到《深入理解Linux内核》...

    233333
  • 灰度图像的 Sobel 边缘检测算法的 HDL实现(二)

    这一步直接通过 HDL 中乘法器的描述来实现, 综合时会自动布线为片内乘法器,如下:

    碎碎思
  • SSH框架之Spring+Struts2+Hibernate整合篇

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    海仔
  • 使用PyInstaller把Python

    2、解压即用(V2.1)。注意环境变量,或者用pyinstaller.py的全路径,或者到解压目录下使用。*^_^*

    py3study
  • Docker容器内的监控命令数据修正思路

    思路概述:编写linux c代码,生成对应的动态链接库(so文件),通过LDPRELOAD实现对/proc文件系统访问的劫持。劫持之后,实现容器内正确的数据计算...

    Walton
  • H3CSE笔记系列 | 带你走进广域网,一篇能让你知道侧重点(可用于知识点复习)

    相当于:在中间运营商打通一根专线,也就是隧道两端地址要在同一网段而且通常使用私网地址。

    网络技术联盟站
  • Tungsten Fabric+K8s轻松上手丨通过Kubernetes网络策略进行应用程序微分段

    本文所有相关链接https://tungstenfabric.org.cn/assets/uploads/files/tf-ceg-case4.pdf

    Tungsten Fabric

扫码关注云+社区

领取腾讯云代金券