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
相關文章:
- 通用的序列號生成器庫 
原文地址:http://www.cnblogs.com/shanyou/p/6241612.html
.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
贊賞
人贊賞
總結
以上是生活随笔為你收集整理的Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 使用熔断器设计模式保护软件
- 下一篇: .NET Core 2.0版本预计于20
