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.
Esse SO é fantastico!
Muito bom artigo.
Abs,