Tôi đã viết một ứng dụng .NET + EF. Mọi thứ hoạt động tốt trên một sợi đơn. Trên nhiều chủ đề - đó là một câu chuyện khác.Thực thể Khung làm mới và cập nhật đồng thời
Trong đối tượng EF của tôi, tôi có bộ đếm nguyên. Thuộc tính này được đánh dấu là "Concurrency Mode = Fixed". Về cơ bản, những gì tôi đang cố gắng làm là cập nhật bộ đếm này trên một số chủ đề. Giống như hoạt động này:
this.MyCounter -= 1;
Bởi vì nó chế độ đồng thời đã được đổi thành "cố định", khi tôi đang Tring để cập nhật một tài sản đó đã thay đổi - một OptimisticConcurrencyException
được ném.
Để giải quyết vấn đề này đồng thời, tôi đang sử dụng mã này:
while (true)
{
try
{
this.UsageAmount -= 1; // Change the local EF object value and call SaveChanges().
break;
}
catch (OptimisticConcurrencyException)
{
Logger.Output(LoggerLevel.Trace, this, "concurrency conflict detected.");
EntityContainer.Instance.Entities.Refresh(RefreshMode.StoreWins, this.InnerObject);
}
}
Kết quả của mã này là vô hạn (hoặc có thể nó chỉ trông giống như) vòng lặp. Mọi cuộc gọi của this.UsageAmount -= 1
ném một số OptimisticConcurrencyException
, làm cho vòng lặp chạy lại.
My EntityContainer.Instance.Entities
là một lớp đơn lẻ cung cấp ngữ cảnh EF PER THREAD. Điều này có nghĩa là mỗi luồng có một ngữ cảnh duy nhất. Mã này:
public sealed class EntityContainer
{
#region Singlethon Implemantation
private static Dictionary<Thread, EntityContainer> _instance = new Dictionary<Thread,EntityContainer>();
private static object syncRoot = new Object();
public static EntityContainer Instance
{
get
{
if (!_instance.ContainsKey(Thread.CurrentThread))
{
lock (syncRoot)
{
if (!_instance.ContainsKey(Thread.CurrentThread))
_instance.Add(Thread.CurrentThread, new EntityContainer());
}
}
return _instance[Thread.CurrentThread];
}
}
private EntityContainer()
{
Entities = new anticopyEntities2();
}
#endregion
anticopyEntities2 _entities;
public anticopyEntities2 Entities
{
get
{
//return new anticopyEntities2();
return _entities;
}
private set
{
_entities = value;
}
}
}
BTW, sau khi gọi Entities.Refresh
phương pháp - có vẻ như nó hoạt động (trạng thái đối tượng là không thay đổi và giá trị propery là chính xác những gì tồn tại trong cơ sở dữ liệu).
Tôi làm cách nào để giải quyết vấn đề tương tranh này?
bạn có thể đăng các mã cho lớp singleton bạn đề cập đến 'EntityContainer.Instance.Entities'? - Chỉ là phần mà bạn đang cung cấp "ngữ cảnh EF cho mỗi chủ đề". – lukiffer
Mã EntityContainer.Instance.Entities được chèn vào bài đăng. – No1Lives4Ever
Khi bạn nói * mọi cuộc gọi * ném, điều này có thể xảy ra với một số chủ đề bị ngăn không cho cập nhật vì chúng bị đánh vào cơ sở dữ liệu mỗi lần không? Giá trị trong DB thực sự có thay đổi không? – shambulator