Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

.NET Entity Framework i transakcje

Tworzenie jednego globalnego Entity Framework DbContext w aplikacji internetowej jest bardzo zła. DbContext Klasa nie jest bezpieczna wątkowo (i te same blokady dla ObjectContext Entity Framework v1 klasa). Jest zbudowany wokół koncepcji jednostki pracy a to oznacza, że ​​używasz go do obsługi pojedynczego przypadku użycia:a więc dla transakcji biznesowej. Ma za zadanie obsłużyć jedno żądanie.

Pojawia się wyjątek, ponieważ dla każdego żądania tworzysz nową transakcję, ale spróbuj użyć tego samego DbContext . Masz szczęście, że DbContext wykrywa to i zgłasza wyjątek, ponieważ teraz dowiedziałeś się, że to nie zadziała.

DbContext zawiera lokalną pamięć podręczną encji w Twojej bazie danych. Pozwala na wprowadzenie wielu zmian i wreszcie przesłanie tych zmian do bazy danych. Podczas korzystania z pojedynczego statycznego DbContext , z wieloma użytkownikami dzwoniącymi do SaveChanges na tym obiekcie, skąd ma wiedzieć, co dokładnie powinno zostać popełnione, a czego nie?

Ponieważ nie wie, uratuje wszystko zmiany, ale w tym momencie inne żądanie może nadal wprowadzać zmiany. Jeśli masz szczęście, albo EF, albo baza danych nie powiedzie się, ponieważ jednostki są w nieprawidłowym stanie. Jeśli masz pecha, podmioty, które są w nieprawidłowym stanie, są pomyślnie zapisywane w bazie danych i możesz dowiedzieć się kilka tygodni później, że Twoje dane zostały uszkodzone.

Rozwiązaniem Twojego problemu jest utworzenie co najmniej jednego DbContext na żądanie . Chociaż teoretycznie możesz buforować kontekst obiektu w sesji użytkownika, jest to również zły pomysł, ponieważ w takim przypadku DbContext zazwyczaj będzie żył zbyt długo i będzie zawierał nieaktualne dane (ponieważ jego wewnętrzna pamięć podręczna nie zostanie automatycznie odświeżona).

Pamiętaj również, że posiadanie jednego DbContext na wątek jest tak samo złe, jak posiadanie jednej instancji dla kompletnej aplikacji internetowej. ASP.NET korzysta z puli wątków, co oznacza, że ​​w okresie istnienia aplikacji internetowej zostanie utworzona ograniczona liczba wątków. Zasadniczo oznacza to, że te DbContext w takim przypadku instancje będą nadal działać przez cały czas życia aplikacji, powodując te same problemy z nieaktualnością danych.

Możesz pomyśleć, że posiadanie jednego DbContext na wątek jest w rzeczywistości bezpieczny wątkowo, ale zwykle tak nie jest, ponieważ ASP.NET ma model asynchroniczny, który umożliwia kończenie żądań w innym wątku niż ten, w którym został uruchomiony (a najnowsze wersje MVC i Web API umożliwiają nawet dowolna liczba wątków obsługuje jedno żądanie w kolejności). Oznacza to, że wątek, który rozpoczął żądanie i utworzył ObjectContext może stać się dostępny do przetworzenia innego żądania na długo przed zakończeniem tego żądania. Jednak obiekty użyte w tym żądaniu (takie jak strona internetowa, kontroler lub dowolna klasa biznesowa) mogą nadal odwoływać się do tego DbContext . Ponieważ nowe żądanie sieciowe działa w tym samym wątku, otrzyma ten sam DbContext wystąpienie jako to, czego używa stare żądanie. To ponownie powoduje wyścig w Twojej aplikacji i powoduje te same problemy z bezpieczeństwem wątków, co jeden globalny DbContext przyczyny wystąpienia.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zakleszczenia programu SQL Server między wyborem/aktualizacją lub wielokrotnym wyborem

  2. Jak podłączyć Sqlcmd do serwera?

  3. Wyszukiwanie pełnotekstowe nie działa, jeśli dołączono słowo zatrzymania, mimo że lista słów zatrzymania jest pusta

  4. policz liczbę spacji w wartościach w serwerze sql

  5. Jak przenieść lub wyeksportować dane SQL Server 2005 do Excela?