2015-10-22 6 views
3

По-видимому (и, вполне возможно) есть недостаток в моей текущей реализации UnitOfWork, потому что у меня есть ошибки соединения при одновременном выполнении многих вызовов.UnitOfWork борется с несколькими одновременными подключениями

Исключение:

Основной поставщик потерпел неудачу на Open.

Внутренняя Исключение:

Подключение не было закрыто. Текущее состояние подключения - .

Это приводит к ответу HTTP 500 на стороне клиента.

реализация UnitOfWork

public class ScopedUnitOfWork : IUnitOfWork 
{ 
    public Entities Context { get; set; } 
    public UnitOfWorkState State { get; set; } 

    public ScopedUnitOfWork(IEnvironmentInformationProvider environmentInformationProvider) 
    { 
     this.Context = new Entities(environmentInformationProvider.ConnectionString); 
     this.State = UnitOfWorkState.Initialized; 
    } 

    public UowScope GetScope() 
    { 
     this.State = UnitOfWorkState.Working; 

     return new UowScope(this); 
    } 

    public SaveResult Save() 
    { 
     if (this.State != UnitOfWorkState.Working) 
      throw new InvalidOperationException("Not allowed to save out of Scope. Request an UowScope instance by calling method GetScope()."); 

     this.Context.SaveChanges(); 

     this.State = UnitOfWorkState.Finished; 

     return new SaveResult(ResultCodes.Ok); 
    } 
} 

Работая на одном UowScope бы решить эту проблему, но это не возможно, учитывая нынешнее обстоятельство, поскольку каждый запрос полностью отделено. Фактически каждый запрос IS использует UoWScope, но, по-видимому, это происходит неправильно, когда UoW получает сразу несколько вызовов.

UoW вводится через Unity IoC, поэтому я полагаю, что это синглтон.

Вопрос

Есть ли способ, чтобы адаптировать UOW так, что отдельные запросы Высокочастотные не проблема?

Предпочтительно ли я решить эту сторону сервера, а не клиентскую сторону, какие-либо советы? Благодаря!

Отказ

Я не утверждаю, я полностью понимаю UOW, поэтому моя реализация может понадобиться улучшение, быть нежным :). Любые улучшения в этом, безусловно, приветствуются!

ОБНОВЛЕНИЕ

Я -know- ФВ контекст является UOW, я использую месторождение на уровне домена, чтобы позволить транзакционной обработки данных, которые связаны функциональность. И это также по требованию клиента, у меня нет выбора.

+4

[DbContext от Entity Framework уже реализует UoW] (http://stackoverflow.com/a/29972845/14357). Что вы имеете здесь, это антиобледенитель UoUoW, – spender

+1

Эхо, что сказал спрятник ... в общем, все, что вам действительно нужно, - это использование (DBContext ctx = new DbContext()) оператора вокруг каждой единицы работы, возможно, с помощью руководства ctx.Connection .Open() и ctx.Connection.Close(). –

+0

@Spikee это должно вас очень заинтересовать ... http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository -and-unit-of-work-patterns-in-as-asp-net-mvc-application –

ответ

3

Проблема заключается в том, что единица рабочего объекта эффективно является синглом, поскольку ваша инфраструктура IoC поддерживает ее в течение всего срока действия вашего приложения. Это означает, что ваш контекст - , также хранится как одноэлементный, так как он находится внутри UoW. Таким образом, вы почти наверняка получите несколько вызовов , вызывающих в вашем контексте, которые будут генерировать исключения.

Однако, я думаю, вы злоупотребляете концепцией того, что должен делать UoW. UoW предлагает контейнер для группы транзакций.Например, скажем, у вас есть платформа для электронной коммерции. Когда вы создаете заказ, вы вставляете строку в таблицу заказов, затем в рамках одной и той же транзакции вы также вставляете строки в таблицу позиций заказов, обновляете точки лояльности пользователей и т. Д. Поэтому вы должны делать все это внутри одного блок работы, совершить его, а затем уничтожить. Пусть среда IoC (Unity в этом случае) создает вашу единицу работы для каждого сеанса.

+0

Это намного ближе к знаку (и действительно полезно), спасибо! – Spikee

Смежные вопросы