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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM