程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Entity Framework Core 實現MySQL 的TimeStamp/RowVersion 並發控制,entityframework並發

Entity Framework Core 實現MySQL 的TimeStamp/RowVersion 並發控制,entityframework並發

編輯:關於.NET

Entity Framework Core 實現MySQL 的TimeStamp/RowVersion 並發控制,entityframework並發


將通用的序列號生成器庫 從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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved