Access
 sql >> Baza danych >  >> RDS >> Access

TRANSACTION_MUTEX i dostęp do transakcji wielosesyjnych

Ostatnio napotkałem wysoki poziom TRANSACTION_MUTEX skumulowany czas oczekiwania w systemie klienta. Nie pamiętam przypadku, w którym widziałem ten typ oczekiwania na szczycie listy „długich oczekiwań” i byłem ciekawy, jakie czynniki mogą popchnąć ten typ ogólnego czasu oczekiwania.

Definicja TRANSACTION_MUTEX w Books Online jest to, że „występuje podczas synchronizacji dostępu do transakcji przez wiele partii”. Niewiele obszarów w silniku SQL Server eksponuje tego typu funkcje, więc moje badanie zostało zawężone do następujących technologii:

  • Przestarzały sp_getbindtoken i sp_bindsession systemowe procedury składowane używane do obsługi połączeń powiązanych
  • Transakcje rozproszone
  • MARS (wiele aktywnych zestawów wyników)

Moim celem było przetestowanie każdej technologii i sprawdzenie, czy ma ona wpływ na TRANSACTION_MUTEX typ oczekiwania.

Pierwszy test, który przeprowadziłem, używał przestarzałego sp_getbindtoken i sp_bindsession procedury składowane. sp_getbindtoken zwraca identyfikator transakcji, który może być następnie użyty przez sp_bindsession aby powiązać wiele sesji razem w ramach tej samej transakcji.

Przed każdym scenariuszem testowym wyczyściłem statystyki oczekiwania mojej testowej instancji SQL Server:

DBCC SQLPERF('waitstats', CLEAR);
GO

Moja testowa instancja programu SQL Server działała pod kontrolą programu SQL Server 2012 SP1 Developer Edition (11.0.3000). Użyłem przykładowej bazy danych Credit, chociaż możesz użyć dowolnego innego rodzaju przykładowej bazy danych, takiej jak AdventureWorks, jeśli chcesz, ponieważ schemat i dystrybucja danych nie są bezpośrednio związane z tematem tego artykułu i nie były konieczne do prowadzenia TRANSACTION_MUTEX czas oczekiwania.

sp_getbindtoken / sp_bindsession

W pierwszym oknie sesji SQL Server Management Studio wykonałem następujący kod, aby rozpocząć transakcję i wyprowadzić token wiązania do rejestracji przez inne zaplanowane sesje:

USE Credit;
GO
 
BEGIN TRANSACTION;
 
DECLARE @out_token varchar(255);
 
EXECUTE sp_getbindtoken @out_token OUTPUT;
 
SELECT @out_token AS out_token;
GO

To zwróciło @out_token z S/Z5_GOHLaGY<^i]S9LXZ-5---.fE--- . W dwóch oddzielnych oknach zapytań SQL Server Management Studio wykonałem następujący kod, aby dołączyć do istniejących sesji (dostęp do współdzielonej transakcji):

USE Credit;
GO
 
EXEC sp_bindsession 'S/Z5_GOHLaGY<^i]S9LXZ-5---.fE---';

A gdy pierwsze okno sesji było nadal otwarte, rozpocząłem następującą pętlę, aby zaktualizować tabelę opłat z datą obciążenia równą bieżącej dacie i godzinie, a następnie wykonałem tę samą logikę w pozostałych dwóch oknach (trzy aktywne sesje w pętla):

WHILE 1 = 1 
BEGIN
    UPDATE  dbo.charge
    SET     charge_dt = SYSDATETIME();
END

Po kilku sekundach anulowałem każde wykonywane zapytanie. Z trzech sesji tylko jedna była w stanie faktycznie wykonać aktualizacje — mimo że pozostałe dwie sesje były aktywnie połączone z tą samą transakcją. A gdybym spojrzał na TRANSACTION_MUTEX typ oczekiwania, widzę, że rzeczywiście się zwiększył:

SELECT  [wait_type],
        [waiting_tasks_count],
        [wait_time_ms],
        [max_wait_time_ms],
        [signal_wait_time_ms]
FROM sys.dm_os_wait_stats
WHERE wait_type = 'TRANSACTION_MUTEX';

Wyniki dla tego konkretnego testu były następujące:

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    2                     181732         93899              0

Widzę więc, że były dwa zadania oczekujące (dwie sesje, które jednocześnie próbowały zaktualizować tę samą tabelę za pomocą pętli). Ponieważ nie wykonałem SET NOCOUNT ON , mogłem zobaczyć, że tylko pierwsza wykonana UPDATE pętla wprowadziła zmiany. Wypróbowałem tę podobną technikę, używając kilku różnych odmian (na przykład – cztery ogólne sesje, z trzema czekającymi) – i TRANSACTION_MUTEX inkrementacja wykazała podobne zachowanie. Widziałem też TRANSACTION_MUTEX akumulacja podczas jednoczesnej aktualizacji innej tabeli dla każdej sesji – więc modyfikacje tego samego obiektu w pętli nie były wymagane w celu odtworzenia TRANSACTION_MUTEX kumulacja czasu oczekiwania.

Transakcje rozproszone

Mój następny test polegał na sprawdzeniu, czy TRANSACTION_MUTEX Zwiększono czas oczekiwania dla transakcji rozproszonych. Do tego testu użyłem dwóch instancji SQL Server i połączonego między nimi serwera połączonego. Usługa MS DTC była uruchomiona i poprawnie skonfigurowana, a ja wykonałem następujący kod, który wykonał lokalne polecenie DELETE i zdalny DELETE za pośrednictwem połączonego serwera, a następnie wycofano zmiany:

USE Credit;
GO
 
SET XACT_ABORT ON;
 
-- Assumes MS DTC service is available, running, properly configured
BEGIN DISTRIBUTED TRANSACTION;
 
DELETE [dbo].[charge] WHERE charge_no = 1;
DELETE [JOSEPHSACK-PC\AUGUSTUS].[Credit].[dbo].[charge] WHERE charge_no = 1;
 
ROLLBACK TRANSACTION;

TRANSACTION_MUTEX nie wykazał żadnej aktywności na lokalnym serwerze:

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    0                     0              0                  0

Jednak liczba oczekujących zadań została zwiększona na zdalnym serwerze:

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    1                     0              0                  0

Więc moje oczekiwanie, że to się potwierdziło – biorąc pod uwagę, że mamy jedną rozproszoną transakcję z więcej niż jedną sesją zaangażowaną w jakiś sposób w tę samą transakcję.

MARS (wiele aktywnych zestawów wyników)

A co z korzystaniem z wielu aktywnych zestawów wyników (MARS)? Czy spodziewalibyśmy się również zobaczyć TRANSACTION_MUTEX gromadzić się, gdy jest powiązany z użyciem MARS?

W tym celu użyłem następującego kodu aplikacji konsoli C# przetestowanej z Microsoft Visual Studio na mojej instancji SQL Server 2012 i bazie danych Credit. Logika tego, co faktycznie robię, nie jest zbyt użyteczna (zwraca jeden wiersz z każdej tabeli), ale czytniki danych są na tym samym połączeniu, a atrybut połączenia MultipleActiveResultSets jest ustawiona na true, więc wystarczyło sprawdzić, czy rzeczywiście MARS może sterować TRANSACTION_MUTEX również akumulacja:

string ConnString = @"Server=.;Database=Credit;Trusted_Connection=True;MultipleActiveResultSets=true;";
SqlConnection MARSCon = new SqlConnection(ConnString);
 
MARSCon.Open();
 
SqlCommand MARSCmd1 = new SqlCommand("SELECT payment_no FROM dbo.payment;", MARSCon);
SqlCommand MARSCmd2 = new SqlCommand("SELECT charge_no FROM dbo.charge;", MARSCon);
 
SqlDataReader MARSReader1 = MARSCmd1.ExecuteReader();
SqlDataReader MARSReader2 = MARSCmd2.ExecuteReader();
 
MARSReader1.Read();
MARSReader2.Read();
 
Console.WriteLine("\t{0}", MARSReader1[0]);
Console.WriteLine("\t{0}", MARSReader2[0]);

Po wykonaniu tego kodu zobaczyłem następującą akumulację dla TRANSACTION_MUTEX :

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    8                     2              0                  0

Jak widać, aktywność MARS (jakkolwiek banalnie zaimplementowana) spowodowała wzrost w TRANSACTION_MUTEX akumulacja typu oczekiwania. A sam atrybut ciągu połączenia nie steruje tym, robi to rzeczywista implementacja. Na przykład usunąłem drugą implementację czytnika i utrzymywałem tylko jeden czytnik z MultipleActiveResultSets=true i zgodnie z oczekiwaniami nie było TRANSACTION_MUTEX kumulacja czasu oczekiwania.

Wniosek

Jeśli widzisz wysoki poziom TRANSACTION_MUTEX czeka w twoim środowisku, mam nadzieję, że ten post da ci pewien wgląd w trzy sposoby do zbadania - aby określić, skąd te oczekiwania pochodzą i czy są konieczne.


No
  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak stworzyć bazę danych inwentaryzacji w programie Microsoft Access

  2. Pytania bez odpowiedzi dotyczące bezpieczeństwa serwera MS SQL i kontroli dostępu

  3. 6 ciekawostek o firmie Microsoft, których prawdopodobnie nie znasz!

  4. Co to jest baza danych zgodna z ODBC?

  5. Światowy dzień tworzenia kopii zapasowych:4 interesujące fakty dotyczące utraty danych