在EF中,處理并發沖突時,我采用了行版本RowVersion。
不過,總覺得有點不好用,比如這次修改了資料庫中某一條資料,update提交之后,客戶端必須再次重新檢索資料,否則如何連續修改的話,就會報錯,因為只讀了一次,卻修改2次,第二次就會報錯。
各位大神,有什么好的處理方式嗎?
uj5u.com熱心網友回復:
你的RowVersion用的不對,RowVersion應該是客戶端產生,而不是資料庫端的自增量。uj5u.com熱心網友回復:
我的RowVersion實作protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//呼叫父類的方法
base.OnModelCreating(modelBuilder);
//將TrackingState欄位排除在EF修改跟蹤的功能之外
modelBuilder.Types<BaseModel>().Configure(x => x.Ignore(y => y.TrackingState));
//登記要進行并發控制的模型表
//ConcurrencyTypes.Add(typeof(sys_user));
//modelBuilder.Entity<sys_user>().Property(p => p.RowVersion).IsConcurrencyToken();
//注冊資料庫自定義函式
//因為EF自帶的DbFunctions實際上實作的是同樣的功能,所以系統函式不需要通過EFDbFunctions定義。不過此代碼仍然有參考意義,在需要用自定義函式時仍然需要使用
modelBuilder.Conventions.Add(new FunctionsConvention("", typeof(ass_EFDbFunctions)));
}
public override int SaveChanges()
{
this.ChangeTracker.DetectChanges();
var entries = this.ChangeTracker.Entries();
//實作資料修改跟蹤和并發控制
foreach (var entry in entries)
{
//只有新增或修改時,才需要進行跟蹤和并發控制
if (entry.State != EntityState.Added && entry.State != EntityState.Modified) continue;
var obj = entry.Entity;
//資料更改跟蹤記錄
if (entry.State == EntityState.Added) //記錄資料創建時間
{
if (obj.HasProperty("CreateTime")) obj.SetPropertyValue("CreateTime", DateTime.Now);
}
else if (entry.State == EntityState.Modified) //記錄資料修改時間
{
if (obj.HasProperty("ModifyTime")) obj.SetPropertyValue("ModifyTime", DateTime.Now);
//因為CreateTime可能并不被客戶端提取,因此客戶端上傳的資料中也缺少CreateTime,因此更新時需要剔除,從而防止被更新為null
entry.Property("CreateTime").IsModified = false;
}
//obj.TrackInfo = "admin"; //記錄跟蹤資訊
//并發控制
if (concurrencyTypes.Count > 0 && concurrencyTypes.Contains(obj.GetType()) && obj.HasProperty("RowVersion"))
{
//設定要新寫入的值(包括新增和修改時,都要寫入新的GUID)
obj.SetPropertyValue("RowVersion", System.Text.Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));
}
}
return base.SaveChanges();
}
uj5u.com熱心網友回復:
很久沒有在.net 這一塊深耕了。不過從你的描述中,不難看出這是一個樂觀鎖,并且使用的cas通過版本號實作。
既然是cas,那么在讀取記錄時,會有一個特定的版本號。
而你的資料提交修改,是客戶端行為,
你之所以兩次提交,都要去查詢資料庫,
是因為你沒有保留第一次提交完成后的新版本號。
粗略估計,還是使用的老版本號。
uj5u.com熱心網友回復:
你的代碼好難哦,看不懂啊。EF利用行版本來處理并發,不是自動的嗎,你怎么RowVersion是客戶端產生呢?客戶端怎么產生啊?....
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/269040.html
標籤:C#
