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

TRANSACTION_MUTEX и достъп до многосесийни транзакции

Наскоро срещнах висок TRANSACTION_MUTEX натрупано време за изчакване в клиентска система. Не можех да си спомня случай, в който видях този тип на изчакване като най-близо до горната част на списъка с „високо чакане“ и ми беше любопитно какви фактори биха могли да доведат до този тип общо време на чакане.

Дефиницията на Books Online за TRANSACTION_MUTEX е, че "се случва по време на синхронизиране на достъп до транзакция от множество партиди." Не много области в двигателя на SQL Server разкриват този тип функционалност, така че моето разследване беше стеснено до следните технологии:

  • Оттегленият sp_getbindtoken и sp_bindsession системни съхранени процедури, използвани за обработка на свързани връзки
  • Разпределени транзакции
  • MARS (множество активни набори от резултати)

Целта ми беше да тествам всяка технология и да видя дали тя е повлияла на TRANSACTION_MUTEX тип чакане.

Първият тест, който направих, използва отхвърления sp_getbindtoken и sp_bindsession съхранени процедури. sp_getbindtoken връща идентификатор на транзакция, който след това може да се използва от sp_bindsession за свързване на няколко сесии заедно за една и съща транзакция.

Преди всеки тестов сценарий се уверих, че изчистих статистиката за чакане на моя тестов екземпляр на SQL Server:

DBCC SQLPERF('waitstats', CLEAR);
GO

Моят тестов екземпляр на SQL Server работеше с SQL Server 2012 SP1 Developer Edition (11.0.3000). Използвах примерната база данни Credit, въпреки че бихте могли да използвате всякакъв друг вид примерна база данни като AdventureWorks, ако искате, тъй като схемата и разпределението на данните не са пряко свързани с темата на тази статия и не е необходимо, за да управлявате TRANSACTION_MUTEX време за изчакване.

sp_getbindtoken / sp_bindsession

В първия прозорец на сесията на SQL Server Management Studio изпълних следния код, за да започна транзакция и да изведа токена за свързване за записване от другите планирани сесии:

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

Това върна @out_token на S/Z5_GOHLaGY<^i]S9LXZ-5---.fE--- . В два отделни прозореца за заявка на SQL Server Management Studio изпълних следния код, за да се присъединя към съществуващите сесии (достъп до споделената транзакция):

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

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

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

След няколко секунди отмених всяка изпълняваща се заявка. От трите сесии само една успя да извърши актуализации – въпреки че другите две сесии бяха активно присъединени към същата транзакция. И ако погледнах TRANSACTION_MUTEX чакам тип, виждам, че наистина се увеличи:

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';

Резултатите за този конкретен тест бяха както следва:

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    2                     181732         93899              0

Така че виждам, че имаше две чакащи задачи (двете сесии, които едновременно се опитваха да актуализират една и съща таблица чрез цикъла). Тъй като не бях изпълнил SET NOCOUNT ON , успях да видя, че само първото изпълнено UPDATE цикълът получи промени. Опитах тази подобна техника, използвайки няколко различни варианта (например – четири общи сесии, с три чакащи) – и TRANSACTION_MUTEX увеличаването показа подобно поведение. Видях и TRANSACTION_MUTEX натрупване при едновременно актуализиране на различна таблица за всяка сесия – така че не са необходими модификации срещу един и същ обект в цикъл, за да се възпроизведе TRANSACTION_MUTEX натрупване на време за изчакване.

Разпределени транзакции

Следващият ми тест включваше проверка дали TRANSACTION_MUTEX времето за изчакване беше увеличено за разпределени транзакции. За този тест използвах два екземпляра на SQL Server и свързан сървър, свързан между тях. MS DTC работеше и беше правилно конфигуриран и аз изпълних следния код, който извърши локално DELETE и дистанционно DELETE чрез свързания сървър и след това връща промените:

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 не показа активност на локалния сървър:

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    0                     0              0                  0

Броят на чакащите задачи обаче беше увеличен на отдалечения сървър:

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    1                     0              0                  0

Така че очакванията ми да видя това се потвърдиха – като се има предвид, че имаме една разпределена транзакция с повече от една сесия, участващи по някакъв начин с една и съща транзакция.

MARS (множество активни набори от резултати)

Какво ще кажете за използването на множество активни набори от резултати (MARS)? Бихме ли очаквали също да видим TRANSACTION_MUTEX се натрупват, когато са свързани с използването на MARS?

За това използвах следния код на конзолното приложение на C#, тестван от Microsoft Visual Studio срещу моя екземпляр на SQL Server 2012 и базата данни Credit. Логиката на това, което всъщност правя, не е много полезна (връща един ред от всяка таблица), но четците на данни са на една и съща връзка и атрибутът на връзката MultipleActiveResultSets е настроен на true, така че беше достатъчно да се провери дали MARS наистина може да управлява TRANSACTION_MUTEX натрупване също:

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]);

След като изпълних този код, видях следното натрупване за TRANSACTION_MUTEX :

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    8                     2              0                  0

Както можете да видите, активността на MARS (колкото и тривиално приложена) предизвика нарастване в TRANSACTION_MUTEX изчакване тип натрупване. И самият атрибут на низ за свързване не управлява това, действителната реализация го прави. Например премахнах втората реализация на четеца и просто поддържах единичен четец с MultipleActiveResultSets=true , и както се очакваше, нямаше TRANSACTION_MUTEX натрупване на време за изчакване.

Заключение

Ако виждате високо TRANSACTION_MUTEX чака във вашата среда, надявам се, че тази публикация ви дава известна представа за три начина, които да проучите – за да определите откъде идват тези изчаквания и дали са необходими или не.


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. Кога е време за надстройка до SQL?

  2. Имате проблеми със срива на MS Access? Опитайте първо тези решения

  3. Как да промените цвета на фона на заглавките на формуляр в Access 2016

  4. TreeView Control с подформуляри

  5. Как се използват базите данни в електронната търговия