Na semana passada vimos um exemplo de Deadlock com SQL Server, e para monitorar e rastrear eventos deste gênero podemos optar por várias alternativas, dentre elas a utilização de Trace Flags e SQL Server Profiler, e também podemos monitorar de forma bem transparente com os eventos do SMO.
De uma maneira bem simples, o código abaixo monitora os eventos de Deadlock de uma determinada instancia do SQL Server, e quando ocorre uma Deadlock, ele informa os SPID que estão relacionadas a este evento, e gera um Deadlock File para obter maiores detalhes sobre o deadlock.
using System; using System.IO; using System.Linq; using System.Xml.Linq; using Microsoft.SqlServer.Management.Smo; namespace DemoSmo { static class DemoEvent3 { public static void Run() { const string serverName = @".\SQLEXPRESS"; var server = new Server(serverName); var eventSet = new ServerTraceEventSet( ServerTraceEvent.LockDeadlock, ServerTraceEvent.LockDeadlockChain, ServerTraceEvent.DeadlockGraph ); server.Events.SubscribeToEvents(eventSet, OnDeadlock); server.Events.StartEvents(); Console.ReadKey(); server.Events.StopEvents(); server.Events.UnsubscribeFromEvents(eventSet); } private static void OnDeadlock(object sender, ServerEventArgs e) { switch (e.EventType) { case EventType.DeadlockGraph: DeadlockGraph(e); break; case EventType.LockDeadlockChain: LockDeadlockChain(e); break; case EventType.LockDeadlock: Console.WriteLine("Data/Hora: {0:dd/MM/yyyy HH:mm}", e.PostTime); Console.WriteLine("Vítima escolhida: SPID {0}", e.Spid); break; } Console.WriteLine(); } private static void LockDeadlockChain(ServerEventArgs e) { var textData = e.Properties.FirstOrDefault(prop => prop.Name == "TextData"); if (textData == null) return; Console.WriteLine("Data/Hora: {0:dd/MM/yyyy HH:mm}", e.PostTime); Console.WriteLine(((string)textData.Value).TrimEnd()); } private static void DeadlockGraph(ServerEventArgs e) { var path = string.Format(@"C:\TEMP\{0}.xdl", Guid.NewGuid()); var textData = e.Properties.FirstOrDefault(prop => prop.Name == "TextData"); if (textData == null) return; var xml = XDocument.Parse(((string)textData.Value)) .Elements("TextData") .Elements("deadlock-list") .FirstOrDefault(); if (xml == null) return; using (var file = new StreamWriter(path)) file.Write(xml.ToString(SaveOptions.DisableFormatting)); Console.WriteLine("Data/Hora: {0:dd/MM/yyyy HH:mm}", e.PostTime); Console.WriteLine("Arquivo gerado: {0}", path); } } }
A execução do código:
Os arquivos gerados:
E um arquivo de deadlock file gerado pelo SMO aberto no SQL Server Management Studio, possuindo informações sobre os processos, os objetos em lock e a query que foi executada.
Assim terminamos os artigos sobre SMO, espero que tenham gostado de conhecer um pouco mais sobre esta feature.