2010-03-30 7 views
5

Po otwarciu połączenia z SQL Server 2005 z naszej aplikacji internetowej, od czasu do czasu zobaczyć ten błąd:SQL Wyjątek: „Personifikuj Bezpieczeństwo Session Context” nie można nazwać w tej partii, ponieważ jednoczesne partii nazwał go

„podszywać Kontekst bezpieczeństwa sesji "nie może zostać wywołany w tej partii, ponieważ wywołała go symultaniczna partia.

Używamy MARS i łączenia połączeń.

Wyjątkiem pochodzi z następującego fragmentu kodu:

protected SqlConnection Open() 
{ 
    SqlConnection connection = new SqlConnection(); 
    connection.ConnectionString = m_ConnectionString; 
    if (connection != null) 
    { 
     try 
     { 
      connection.Open(); 
      if (m_ExecuteAsUserName != null) 
      { 
       string sql = Format("EXECUTE AS LOGIN = {0};", m_ExecuteAsUserName); 
       ExecuteCommand(connection, sql); 
      } 
     } 
     catch (Exception exception) 
     { 
      connection.Close(); 
      connection = null; 
     } 
    } 
    return connection; 
} 

znalazłem MS Connect article co sugeruje, że błąd jest spowodowany gdy poprzednia komenda nie została jeszcze rozwiązana przed poleceniem EXECUTE AS LOGIN zostanie wysłana. Ale jak to może być, jeśli połączenie zostało dopiero co otwarte?

Czy może to mieć coś wspólnego z łączeniem puli, który oddziałuje dziwnie na MARS?

AKTUALIZACJA: Na krótką metę wdrożyliśmy obejście, usuwając pulę połączeń w dowolnym momencie, aby pozbyć się złego połączenia, ponieważ w przeciwnym razie zostanie ono przekazane różnym użytkownikom. (Dzieje się to teraz 5-10 razy dziennie z niewielką liczbą równoczesnych użytkowników, więc jest dość denerwujące.) Ale jeśli ktoś ma jakieś dalsze pomysły, wciąż szukamy prawdziwego rozwiązania ...

Odpowiedz

2

powiedziałbym, że Mars, a następnie łączenie

Od „Using Multiple Active Result Sets (MARS)

  • Applications can have multiple default result sets open and can interleave reading from them.
  • Applications can execute other statements (for example, INSERT, UPDATE, DELETE, and stored procedure calls) while default result sets are open.

Pule połączeń w to forma podstawowa oznacza połączenie otwieranie/zamykanie napowietrznych jest zminimalizowane, ale każde połączenie (do MARS) ma jedno dzieje się w tym samym czasie. Pooling istnieje od jakiegoś czasu i po prostu działa po wyjęciu z pudełka.

MARS (nie używałem tego BTW) wprowadza nakładające się "rzeczy" dotyczące pojedynczego połączenia. Więc to chyba MARS zamiast buforowanie połączeń jest większa sprawcą 2.

Od „Extending Database Impersonation by Using EXECUTE AS

When impersonating a principal by using the EXECUTE AS LOGIN statement, or within a server-scoped module by using the EXECUTE AS clause, the scope of the impersonation is server-wide.

To może wyjaśniać, dlaczego MARS jest przyczyną go: ten sam główny w 2 sesji zarówno z systemem EXECUTE AS . Być może coś w tym przepisie użytkowania, lub spróbuj tego:

IF ORIGINAL_LOGIN() = SUSER_SNAME() EXECUTE AS LOGIN = {0}; 

Na refleksji i po przeczytaniu tej odpowiedzi, mam przekonanie, że nie próbuje zmienić kontekst wykonania dla każdej sesji (MARS) w jednym Połączenia to dobry pomysł ...

+1

Dziękuję za odpowiedź. Zgadzam się, że musi to mieć coś wspólnego z MARS, ale z pewnością wiele zestawów wyników dotyczy pojedynczych połączeń. I moje połączenie nie ma żadnych poprzednich zestawów wyników, ponieważ dopiero co go otworzyłem i jest "nowe" (chociaż z puli). Myślę, że w twoim drugim cytacie, gdzie jest napisane "zakres podszywania się jest dla całego serwera", oznacza to tylko dla bieżącego połączenia. – kasey

+0

@kasey: Domyślam się, że pojedyncze połączenie ma wiele sesji, a EXECUTE AS na sesję. Kiedy połączenie zostanie ponownie użyte z puli, domyślam się, że przełącznik kontekstu jest nadal ustawiony. hmm. Być może jest to po prostu połączenie połączeń i EXECUTE AS ... Interesujące pytanie masz tutaj :-) – gbn

0

Czy próbowałeś użyć odwrócenia na końcu wyciągu sql?

http://msdn.microsoft.com/en-us/library/ms178632.aspx

Zawsze to zrobić po prostu upewnij się, że obecna sytuacja wraca do normy.

+0

Dobry pomysł, ale tak - mamy try/catch bloki, aby zapewnić, że to zrobimy, plus masz inny rodzaj błędu, jeśli zapomnisz zrób to ("POZOSTAŁY BŁĄD", który jest również rejestrowany przez SQL Server). – kasey

1

Nie obwiniaj łączenia połączeń - MARS jest dość znany z powodu spustoszenia. To nie do końca wina, ale jest to połowa i połowa.Kluczową rzeczą do zapamiętania jest to, że MARS jest zaprojektowany i działa tylko z "normalnym" użyciem DB (co oznacza, regularne rzeczy CRUD bez partii administracyjnych). Wszelkie polecenia, które mają szeroki wpływ na silnik DB, mogą wyzwolić MARS, nawet jeśli jest to tylko jedno połączenie i jeden wątek (np. Uruchamianie partii konfiguracji w celu utworzenia tabel lub transakcji zagnieżdżonej).

Powiedziawszy to, można z łatwością obwiniać MARS, ale działa całkiem dobrze dla normalnych scenariuszy CRUD, które są jak 99% (i rzeczy o niskiej skuteczności takiej jak ORM-y i LINQ zależą od tego dla życia). Oznacza to, że ważne jest, aby ludzie dowiedzieli się, że jeśli chcą zhackować SQL przez połączenie, nie mogą używać MARS. Na przykład miałem kod instalacyjny, który tworzył całą bazę od zera, ponieważ jest bardzo wygodny do wdrożenia, ale użyczał żądań połączenia z usługą sieciową, którą wdrażał - oops :-) Zajęło mi kilka dni kopania, aby nauczyć się mojej lekcji . Tak więc po prostu utrzymuję separację obaw (która jest zawsze dobra) i problemy zniknęły.

Powiązane problemy