Access
 sql >> Base de données >  >> RDS >> Access

TRANSACTION_MUTEX et accès aux transactions multi-sessions

J'ai récemment rencontré un niveau élevé de TRANSACTION_MUTEX temps d'attente cumulé sur un système client. Je ne me souvenais pas d'un cas où j'avais vu ce type d'attente en haut de la liste des "attentes élevées" et j'étais curieux de savoir quels facteurs pouvaient augmenter ce type de temps d'attente global.

La définition de la documentation en ligne de TRANSACTION_MUTEX est qu'il "se produit lors de la synchronisation de l'accès à une transaction par plusieurs lots". Peu de domaines du moteur SQL Server exposent ce type de fonctionnalité, donc mon enquête s'est limitée aux technologies suivantes :

  • Le sp_getbindtoken obsolète et sp_bindsession procédures stockées système utilisées pour gérer les connexions liées
  • Transactions distribuées
  • MARS (ensembles de résultats actifs multiples)

Mon objectif était de tester chaque technologie et de voir si elle influençait le TRANSACTION_MUTEX type d'attente.

Le premier test que j'ai effectué utilisait le sp_getbindtoken obsolète et sp_bindsession procédures stockées. Le sp_getbindtoken renvoie un identifiant de transaction qui peut ensuite être utilisé par sp_bindsession pour lier plusieurs sessions ensemble sur la même transaction.

Avant chaque scénario de test, je me suis assuré d'effacer les statistiques d'attente de mon instance SQL Server de test :

DBCC SQLPERF('waitstats', CLEAR);
GO

Mon instance SQL Server de test exécutait SQL Server 2012 SP1 Developer Edition (11.0.3000). J'ai utilisé l'exemple de base de données Credit, bien que vous puissiez utiliser n'importe quel autre type d'exemple de base de données comme AdventureWorks si vous le souhaitez, car le schéma et la distribution des données ne sont pas directement pertinents pour le sujet de cet article et n'étaient pas nécessaires pour conduire le TRANSACTION_MUTEX temps d'attente.

sp_getbindtoken / sp_bindsession

Dans la première fenêtre de session de SQL Server Management Studio, j'ai exécuté le code suivant pour commencer une transaction et générer le jeton de liaison pour l'inscription par les autres sessions planifiées :

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

Cela a renvoyé un @out_token de S/Z5_GOHLaGY<^i]S9LXZ-5---.fE--- . Dans deux fenêtres de requête SQL Server Management Studio distinctes, j'ai exécuté le code suivant pour rejoindre les sessions existantes (accès à la transaction partagée) :

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

Et avec la première fenêtre de session toujours ouverte, j'ai commencé la boucle suivante pour mettre à jour la table de la table de facturation avec une date de facturation égale à la date et à l'heure actuelles, puis j'ai exécuté la même logique dans les deux autres fenêtres (trois sessions actives dans la boucle):

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

Après quelques secondes, j'ai annulé chaque requête en cours d'exécution. Sur les trois sessions, une seule a pu réellement effectuer des mises à jour, même si les deux autres sessions étaient activement associées à la même transaction. Et si je regardais le TRANSACTION_MUTEX type d'attente, je peux voir qu'il a effectivement incrémenté :

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

Les résultats de ce test particulier étaient les suivants :

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    2                     181732         93899              0

Je vois donc qu'il y avait deux tâches en attente (les deux sessions qui essayaient simultanément de mettre à jour la même table via la boucle). Comme je n'avais pas exécuté SET NOCOUNT ON , j'ai pu voir que seul le premier UPDATE exécuté loop a reçu des modifications. J'ai essayé cette technique similaire en utilisant quelques variantes différentes (par exemple - quatre sessions globales, avec trois en attente) - et le TRANSACTION_MUTEX l'incrémentation a montré un comportement similaire. J'ai aussi vu le TRANSACTION_MUTEX accumulation lors de la mise à jour simultanée d'une table différente pour chaque session ; ainsi, les modifications sur le même objet dans une boucle n'étaient pas nécessaires pour reproduire le TRANSACTION_MUTEX accumulation de temps d'attente.

Transactions distribuées

Mon prochain test consistait à voir si TRANSACTION_MUTEX le temps d'attente a été incrémenté pour les transactions distribuées. Pour ce test, j'ai utilisé deux instances SQL Server et un serveur lié connecté entre les deux. MS DTC était en cours d'exécution et correctement configuré, et j'ai exécuté le code suivant qui a effectué un DELETE local et un DELETE distant via le serveur lié, puis annulé les modifications :

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;

Le TRANSACTION_MUTEX n'a montré aucune activité sur le serveur local :

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    0                     0              0                  0

Cependant le nombre de tâches en attente a été incrémenté sur le serveur distant :

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    1                     0              0                  0

Donc, mon attente de voir cela a été confirmée - étant donné que nous avons une transaction distribuée avec plus d'une session impliquée d'une manière ou d'une autre dans la même transaction.

MARS (ensembles de résultats actifs multiples)

Qu'en est-il de l'utilisation de plusieurs ensembles de résultats actifs (MARS) ? Est-ce que nous nous attendrions également à voir TRANSACTION_MUTEX s'accumuler lorsqu'il est associé à l'utilisation de MARS ?

Pour cela, j'ai utilisé le code d'application de console C # suivant testé à partir de Microsoft Visual Studio par rapport à mon instance SQL Server 2012 et à la base de données de crédit. La logique de ce que je fais réellement n'est pas très utile (renvoie une ligne de chaque table), mais les lecteurs de données sont sur la même connexion et l'attribut de connexion MultipleActiveResultSets est défini sur true, il suffisait donc de vérifier si MARS pouvait effectivement piloter TRANSACTION_MUTEX accumulation aussi :

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

Après avoir exécuté ce code, j'ai vu l'accumulation suivante pour TRANSACTION_MUTEX :

wait_type            waiting_tasks_count   wait_time_ms   max_wait_time_ms   signal_wait_time_ms
TRANSACTION_MUTEX    8                     2              0                  0

Donc, comme vous pouvez le voir, l'activité MARS (même si elle est implémentée de manière triviale) a provoqué une légère hausse dans le TRANSACTION_MUTEX attente type accumulation. Et l'attribut de chaîne de connexion lui-même ne le pilote pas, l'implémentation réelle le fait. Par exemple, j'ai supprimé l'implémentation du deuxième lecteur et je n'ai maintenu qu'un seul lecteur avec MultipleActiveResultSets=true , et comme prévu, il n'y avait pas de TRANSACTION_MUTEX accumulation de temps d'attente.

Conclusion

Si vous voyez un niveau élevé de TRANSACTION_MUTEX d'attente dans votre environnement, j'espère que cet article vous donnera un aperçu de trois pistes à explorer - pour déterminer à la fois d'où viennent ces attentes et si elles sont nécessaires ou non.


No