Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

.NET Entity Framework и транзакции

Създаване на една глобална Entity Framework DbContext в уеб приложение е много лошо. DbContext класът не е безопасен за нишки (и същото важи за ObjectContext на Entity Framework v1 клас). Той е изграден около концепцията за работна единица и това означава, че го използвате, за да работите с един случай на употреба:следователно за бизнес транзакция. Той е предназначен да обработва една единствена заявка.

Изключението, което получавате, се случва, защото за всяка заявка създавате нова транзакция, но опитайте да използвате същия DbContext . Имате късмет, че DbContext открива това и хвърля изключение, защото сега разбрахте, че това няма да работи.

DbContext съдържа локален кеш на обекти във вашата база данни. Тя ви позволява да направите куп промени и накрая да изпратите тези промени в базата данни. Когато използвате единичен статичен DbContext , като множество потребители извикват SaveChanges на този обект, как трябва да се знае какво точно трябва да бъде ангажирано и какво не?

Тъй като не знае, ще запази всички промени, но в този момент друга заявка може все още да прави промени. Когато имате късмет, EF или вашата база данни ще се провалят, защото обектите са в невалидно състояние. Ако нямате късмет, обектите, които са в невалидно състояние, се записват успешно в базата данни и може да разберете седмици по-късно, че данните ви са повредени.

Решението на вашия проблем е да създадете поне един DbContext на заявка . Въпреки че на теория можете да кеширате контекст на обект в потребителската сесия, това също е лоша идея, защото в този случай DbContext обикновено ще живее твърде дълго и ще съдържа остарели данни (тъй като неговият вътрешен кеш няма да се опреснява автоматично).

Също така имайте предвид, че наличието на един DbContext на нишка е почти толкова лошо, колкото да имате един единствен екземпляр за цялото уеб приложение. ASP.NET използва набор от нишки, което означава, че ограничен брой нишки ще бъдат създадени по време на живота на уеб приложението. Това основно означава, че тези DbContext екземплярите в този случай ще продължат да съществуват през целия живот на приложението, причинявайки същите проблеми с остарелостта на данните.

Може би си мислите, че наличието на един DbContext на нишка всъщност е безопасна за нишка, но това обикновено не е така, тъй като ASP.NET има асинхронен модел, който позволява завършване на заявки в нишка, различна от тази, от която е стартирана (и най-новите версии на MVC и Web API дори позволяват произволен брой нишки обработват една заявка в последователен ред). Това означава, че нишката, която е стартирала заявка и е създала ObjectContext може да стане достъпен за обработка на друга заявка много преди тази първоначална заявка да приключи. Обектите, използвани в тази заявка обаче (като уеб страница, контролер или всякаква бизнес класа), все пак може да препращат към този DbContext . Тъй като новата уеб заявка се изпълнява в същата нишка, тя ще получи същия DbContext пример като това, което използва старата заявка. Това отново причинява условия на състезание във вашето приложение и причинява същите проблеми с безопасността на нишката като това, което има един глобален DbContext причини за екземпляр.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Групова актуализация в C#

  2. Проверете/променете нивото на съвместимост на база данни в SQL Server (SSMS)

  3. Посочване на име на колона като параметър в израза SELECT?

  4. Как да изпълня MSSQL съхранена процедура с ADOdb PHP библиотека?

  5. Как мога да определя статуса на дадена работа?