我有一個WCF Web服務,目前遇到一些併發問題。目前負載很小,但預計在未來幾天內會增加很多。該操作無法完成,因爲DbContext已處理 - LifestylePerWcfOperation
整體設置是WCF,實體框架6,依賴注入(Castle Windsor),UnitOfWork &存儲庫模式。
我設置的是打服務並行,我可以重新併發性錯誤,例如壓力測試....
- 同時提交數據庫事務,但它不能在是否決定報告了錯誤事務在數據庫服務器上成功或失敗。
對數據庫的更改已成功提交,但更新對象上下文時發生錯誤。 ObjectContext可能處於不一致的狀態。內部異常消息:由於對象的鍵值與ObjectStateManager中的另一個對象衝突,因此AcceptChanges無法繼續。在調用AcceptChanges之前確保鍵值是唯一的。
屬性「ID」是對象的關鍵信息的一部分,無法修改。
從我所做的研究,它看起來像我應該注入我的DbContext與LifestylePerWcfOperation。目前正在使用LifestyleTransient完成。
當我切換到LifestylePerWcfOperation並重新運行測試,我這個每次都遇到:
- 因爲的DbContext已經佈置
操作無法完成,所以,我真的有2個問題:
- 我正確的假設真正的解決辦法是將我的DbContext切換到LifestylePerWcfOperation?
- 如果是這樣,爲什麼我的DbContext正在被吞噬?
下面是一些代碼:
AppStart.cs:
IocContainer.AddFacility<TypedFactoryFacility>();
IocContainer.Register(Component.For<IRepositoryFactory>().AsFactory());
IocContainer.Register(Component.For<IUnitOfWork>()
.ImplementedBy<UnitOfWork>)
/*.LifestylePerWcfOperation()*/);
IocContainer.Register(Component.For(typeof(IDbContext))
.ImplementedBy(dbContextType)
.DependsOn(Dependency.OnValue("connectionString", String.Format(ConfigurationManager.ConnectionStrings["---"].ConnectionString))));
/*.LifestylePerWcfOperation()*/
IocContainer.Register(Component.For(typeof(IRepository<>))
.ImplementedBy(typeof(Repository<>))
.LifestyleTransient()
/*.LifestylePerWcfOperation()*/);
// Register the actual dbContextType so consuming applications can access it without an interface
IocContainer.Register(Component.For(dbContextType)
.Named(dbContextType.Name)
.DependsOn(Dependency.OnValue("connectionString", String.Format(ConfigurationManager.ConnectionStrings["----"].ConnectionString)));
/*.LifestylePerWcfOperation()*/
UnitOfWork.cs:
public class UnitOfWork : IUnitOfWork
{
private readonly IDbContext _dbContext;
private bool _disposed;
public UnitOfWork(IDbContext dbContext)
{
_dbContext = dbContext;
}
public int Commit()
{
return _dbContext.SaveChanges();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_dbContext.Dispose();
}
_disposed = true;
}
}
}
Repository.cs
public class Repository<T> : IRepository<T> where T : class
{
private readonly IDbSet<T> _dbset;
public Repository(IDbContext dbContext)
{
_dbset = dbContext.Set<T>();
}
public IQueryable<T> Query()
{
return _dbset.AsQueryable();
}
public virtual IEnumerable<T> GetAll()
{
return _dbset.AsEnumerable();
}
public virtual void Add(T entity)
{
_dbset.Add(entity);
}
public virtual void Delete(T entity)
{
_dbset.Remove(entity);
}
public virtual void Delete(ICollection<T> entities)
{
entities.ToList().ForEach(Delete);
}
}
如果需要,我可以添加更多的代碼。感謝您的任何幫助,您可以提供!!
您的DBContext註冊並未指定生活方式,因此Windsor的默認設置將適用:Singleton。這肯定會造成問題。 –