Dlaczego TransactionScope nie działa z Entity Framework?

Patrz poniższy kod. Jeśli zainicjalizuję więcej niż jeden kontekst encji, wtedy otrzymuję następujący wyjątek na 2. zestawie kodu tylko . Jeśli skomentuję drugi zestaw to działa.

{"podstawowy dostawca nie powiódł się na Open."}

Inner: {"komunikacja z podstawowym menedżerem transakcji nie powiodła się."}

Inner: {"Błąd HRESULT E_FAIL został zwrócony z wywołania do komponentu COM."}

Zauważ, że jest to przykładowa aplikacja i Wiem, że nie ma sensu tworzyć 2 kontekstów z rzędu. Jednak kod produkcyjny ma powód do tworzenia wielu kontekstów w tym samym TransactionScope i nie można tego zmienić.

Edit

Oto poprzednie pytanie o to, że próbuję skonfigurować MS-DTC. Wydaje się, że jest on włączony zarówno na serwerze, jak i u klienta. Nie jestem pewien, czy jest poprawnie skonfigurowany. Zauważ również, że jednym z powodów, dla których próbuję to zrobić, jest to, że istniejący kod w TransactionScope używa ADO.NET i Linq 2 Sql... Chciałbym, aby Ci również korzystali z tej samej transakcji. (To pewnie brzmi szalenie, ale muszę to zrobić, jeśli to możliwe).

Jak używać TransactionScope w C#?

Rozwiązanie

Zapora systemu Windows blokowała połączenia z MS-DTC.

using(TransactionScope ts = new System.Transactions.TransactionScope())
        {
                using (DatabaseEntityModel o = new DatabaseEntityModel())
                {
                    var v = (from s in o.Advertiser select s).First();
                    v.AcceptableLength = 1;
                    o.SaveChanges();
                }

                //-> By commenting out this section, it works
                using (DatabaseEntityModel o = new DatabaseEntityModel())
                {
                    //Exception on this next line
                    var v = (from s1 in o.Advertiser select s1).First();                         v.AcceptableLength = 1;
                    o.SaveChanges();
                }
                //->

                ts.Complete();
        }
Author: Community, 2009-04-27

8 answers

Twój MS-DTC (Distributed transaction co-ordinator) nie działa poprawnie z jakiegoś powodu. MS-DTC jest używany do koordynowania wyników transakcji między wieloma heterogenicznymi zasobami, w tym wieloma połączeniami sql.

Spójrz na ten link Aby uzyskać więcej informacji na temat tego, co się dzieje.

Zasadniczo jeśli upewnisz się, że Twój MS-DTC działa poprawnie, nie powinieneś mieć problemów z używaniem 2 ADO.NET połączenia - czy są to ramy podmiotowe połączenia lub innego typu.

 19
Author: Steve Willcock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-27 18:54:21

Możesz uniknąć korzystania z rozproszonej transakcji, zarządzając własnym EntityConnection i przekazując ten EntityConnection do ObjectContext. W przeciwnym razie sprawdź to.

Http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=580828&SiteID=1&mode=1 http://forums.microsoft.com/msdn/showpost.aspx?postid=113669&siteid=1&sb=0&d=1&at=7&ft=11&tf=0&pageid=1

EntityConnection conn = new EntityConnection(ConnectionString);

using (TransactionScope ts = new TransactionScope())
{
    using (DatabaseEntityModel o = new DatabaseEntityModel(conn))
    {
            var v = (from s in o.Advertiser select s).First();
            v.AcceptableLength = 1;
    }

    //-> By commenting out this section, it works
    using (DatabaseEntityModel o = new DatabaseEntityModel(conn))
    {
        //Exception on this next line
        var v = (from s1 in o.Advertiser select s1).First();
                v.AcceptableLength = 1;
    }
    //->

    ts.Complete();
}
 19
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-27 18:48:15

Dodaj C:\Windows\msdtc.exe do wyjątków firewall zarówno na firewall i serwer. Spędziłem wieki monkeying wokół otwierania konkretnych numerów portów i zakresów bez skutku, zanim to zrobiłem.

 5
Author: burnside,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-06 09:29:54

Mam zamiar trzymać to tutaj, ponieważ spędziłem 3 godziny z kolegą wczoraj debugowania tego problemu. Każda odpowiedź mówi, że zawsze jest to problem z firewallem, jednak w naszym przypadku tak nie było. mam nadzieję, że oszczędzi to komuś innego bólu.

Sytuacja, w jakiej się znajdujemy, jest taka, że jesteśmy obecnie w trakcie migracji do struktury podmiotu. Oznacza to, że mamy części kodu, w których wewnątrz pojedynczej transakcji połączenia są otwierane zarówno bezpośrednio za pomocą new SqlConnection(connectionString).Open() i pośrednio za pomocą kontekstu danych EF.

To działa dobrze w naszej aplikacji przez jakiś czas, ale kiedy zaczęliśmy retrospektywnie przejść i umieścić testy wokół kodu, który działał w produkcji, kod wykonany z runnera testowego nadal rzucać ten błąd po raz pierwszy obiekt EF próbował połączyć się z bazą danych po bezpośrednie połączenie zostało wykonane w tej samej transakcji.

Przyczyną błędu w końcu okazało się, że jeśli nie podajesz argumentu Application Name= do łańcucha połączenia, struktura encji domyślnie dodaje jeden (coś w rodzaju EntityFrameworkMUF). Oznacza to, że masz dwa różne połączenia w swojej puli połączeń:

  1. ten, który otwierasz ręcznie bez Application Name= argumentu
  2. automatycznie generowany przyrostek Application Name=EntityFrameworkMUF

I nie jest możliwe otwarcie dwóch odrębnych połączeń wewnątrz jednej transakcji. Kod produkcji określał nazwę Aplikacji; stąd zadziałało, kod testowy nie. Podanie argumentu Application Name= naprawiło błąd.

 4
Author: satnhak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-29 09:05:34

BTW powinieneś rozważyć użycie SaveChanges (false) w połączeniu z AcceptChanges () podczas korzystania z jawnych transakcji takich jak ta.

W ten sposób, jeśli coś się nie powiedzie w SaveChanges( false), ObjectContext nie odrzuci Twoich zmian, więc możesz później ponownie zastosować lub zrobić rejestrowanie błędów itp.

Zobacz ten post, aby uzyskać więcej informacji: http://blogs.msdn.com/alexj/archive/2009/01/11/savechanges-false.aspx

Cheers

Alex

 3
Author: Alex James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-02 00:06:46

Problem polega na tym, że 2 różne DataContext skutecznie tworzą dwa różne połączenia.

W takim przypadku transakcja musi być promowana do transakcji rozproszonej. Zakładam, że twój problem wynika z konfiguracji MS DTC (Microsoft Distributed Transaction Coordinator) na serwerze i lub kliencie. Jeśli serwer nie jest skonfigurowany tak, aby zezwalał na zdalne połączenia na przykład dla MSDTC, napotkasz taki wyjątek.

Możesz odnieść się do tego MS Strona na przykład do rozwiązywania problemów z MSDTC, a google jest wypełnione po brzegi artykułami / pytaniami na temat forum.

Teraz, to może być coś innego, ale naprawdę brzmi jak to jest problem MSDTC.

 1
Author: Denis Troller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-27 18:53:19

Napisałem odpowiedź w innym pytaniu o to, jak diagnozować nieudane transakcje MSDTC.

Ta odpowiedź może okazać się pomocna.

Jak włączyć MSDTC na SQL Server?

 0
Author: Davy Landman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:51

Miałem podobne błędy podczas korzystania z DTC podczas odczytu wiadomości z kolejki MQ, przetwarzania ich i przechowywania w bazie danych SQL 2005 Express Edition. Nie mam wystarczająco dużo czasu, aby zbadać do końca, czy 2005 lub excatly Express edition spowodował ten problem, ale przejście na Standard 2008 wyblakło to konkretne zachowanie.

 0
Author: Valdis Iljuconoks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-03 03:29:16