此问题涉及使用Microsoft Entity Framework处理许多插入或更新的最佳实践.问题是我们编写了一个长期运行的程序,它从数据库中回收了数千条记录,然后逐个更新每条记录上的单个字段.令我们沮丧的是,我们意识到更新的每个记录都会在未处理ObjectContext的时间内被锁定.下面是一些伪代码(实际上没有运行)来说明:
using(ObjectContext context = new ObjectContext())
{
var myRecords = context.CreateObjectSet<MyType>().AsQueryable();
foreach(var record in myRecords)
{
record.MyField = "updated!";
context.SaveChanges();
//--do something really slow like call an external web service
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我们需要做很多更新而不考虑交易.我们惊讶地发现调用context.SaveChanges()实际上会在记录上创建锁,并且在释放ObjectContext之前不会释放它.我们特别不想锁定数据库中的记录,因为这是一个高流量系统,程序可能会运行数小时.
所以问题是:在Microsoft Entity Framework 4中进行许多更新的最佳方法是什么,而不是在锁定数据库的一个长事务上完成所有更新?我们希望答案不是为每个更新创建一个新的ObjectContext ......
我们遇到AppFabric问题,导致出现以下错误:
Exception type: ArgumentException
Exception message: An item with the same key has already been added.
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Microsoft.ApplicationServer.Caching.DataCacheFactory.CreateRoutingClient(String cacheName, NamedCacheConfiguration config)
at Microsoft.ApplicationServer.Caching.DataCacheFactory.CreateNewCacheClient(DataCacheDeploymentMode mode, String cacheName, NamedCacheConfiguration config, IClientChannel channel)
at Microsoft.ApplicationServer.Caching.DataCacheFactory.GetCache(String cacheName)
at Microsoft.ApplicationServer.Caching.DataCacheFactory.GetDefaultCache()
... our code where we are attempting to retrieve a cache item from the default cache by its key
Run Code Online (Sandbox Code Playgroud)
这个错误在我们的测试环境中很少发生(我们没有找到按需重现问题的方案),但似乎总是在每次部署之后在我们的生产环境中发生.我们的部署是自动化的,我们已经验证了部署到各种环境的步骤是相同的.
我们针对给定环境的服务器设置如下:
这些服务器是负载平衡的.已在两个应用程序上启用AppFabric本地缓存.我们的测试和生产服务器设置相同.我们知道将AppFabric放在专用服务器上会更好,但不要认为这会导致/解决此问题.
我们对此问题感到困惑,因为我们在网上其他地方没有发现任何提及它,因为堆栈跟踪似乎表明这是AppFabric本身的一个问题.异常提到插入内容,但是当发生这种情况时我们正在尝试从DataCacheFactory获取默认缓存,以便我们可以从中检索项目.那么,这个错误意味着什么以及我们如何解决它?
更新
这是我用来DataCacheFactory从缓存中创建和提取数据的代码:
private static readonly Lazy<DataCacheFactory> …Run Code Online (Sandbox Code Playgroud)