Hello All,
I set up an Event Notification to fire when a deadlock occurs. I also setup SQL Alerts to make sure DBAs are alerted to deadlocks one way or the other. The problem is, the EVENT NOTIFICATION does not seems to fire at all. I simulated deadlocks and made sure that the Alerts do email DBAs. The Alerts work but not EVENT NOTIFICATION. Any suggestions?
SQLServer 2012 (11.0.5556.0) Enterprise Edition
rgn
USE [master] GO drop DATABASE [DBAArchive] CREATE DATABASE [DBAArchive] CONTAINMENT = NONE ON PRIMARY( NAME = N'DBAArchive', FILENAME = N'S:\MSSQL\DATA\DBAArchive.mdf', SIZE =4096KB, MAXSIZE = UNLIMITED, FILEGROWTH =1024KB) LOG ON( NAME = N'DBAArchive_log', FILENAME = N'S:\MSSQL\DATA\DBAArchive_log.ldf', SIZE =4096KB, MAXSIZE =2048GB, FILEGROWTH =10%) GO ALTER DATABASE [DBAArchive] SET ENABLE_BROKER WITH NO_WAIT GO ALTER DATABASE [DBAArchive] SET TRUSTWORTHY ON-- create the table that will hold our deadlock info CREATE TABLE EventNotification(Id INT IDENTITY(1,1),EventMsg xml,EventDate datetime default(GETDATE())) GO CREATE TABLE EventNotificationMessage(Id INT IDENTITY(1,1),EventMsg xml,EventDate datetime default(GETDATE())) GO--this procedure will write ourevent data into the table and send the notification email CREATE PROCEDURE dbo.usp_ProcessNotification AS DECLARE @msgBody XML DECLARE @dlgId uniqueidentifierDeclare@DefaultProfileName varchar(100)select@DefaultProfileName= P.Namefrom msdb.dbo.sysmail_profile PInnerJoin msdb.dbo.sysmail_principalprofile PPOn P.profile_id = PP.profile_idWhere is_default =1-- you can change this to get all messages at once WHILE(1=1)BEGINBEGIN TRANSACTIONBEGIN TRY-- receive messages from the queue one by one;RECEIVE TOP(1)@msgBody= message_body,@dlgId= conversation_handle FROM dbo.DeadLockNotificationsQueue--exitwhen the whole queue has been processed IF @@ROWCOUNT=0BEGIN IF @@TRANCOUNT>0BEGIN ROLLBACK;END BREAK;END-- insert event data intoour table INSERT INTO EventNotification(eventMsg) SELECT @msgBody DECLARE @MailBody NVARCHAR(MAX) SELECT @MailBody= CAST(@msgBody AS NVARCHAR(MAX));-- send an email with the defined email profile.-- since thisis async it doesn't halt execution EXEC msdb.dbo.sp_send_dbmail @profile_name = @DefaultProfileName, @recipients = 'abc@xyz.com', -- your email @subject = 'Deadlock occured.', @body = @MailBody; -- select * from msdb..sysmail_profile IF @@TRANCOUNT > 0 BEGIN COMMIT; END END TRY BEGIN CATCH IF @@TRANCOUNT > 0 BEGIN ROLLBACK; END -- write any error in to the event log DECLARE @errorNumber BIGINT, @errorMessage nvarchar(2048), @dbName nvarchar(128) SELECT @errorNumber = ERROR_NUMBER(), @errorMessage = ERROR_MESSAGE(), @dbName = DB_NAME() RAISERROR (N'Error WHILE receiving ServiceBroker message FROM queue DeadLockNotificationsQueue. DATABASE Name:%s;Error number:%I64d;ErrorMessage:%s', 16, 1, @dbName, @errorNumber, @errorMessage) WITH LOG; END CATCH; END GO -- create the notification queue that will receive the event notification messages -- add the activation stored procedure that will process the messages in the queue -- as they arrive CREATE QUEUE DeadLockNotificationsQueue WITH STATUS = ON, ACTIVATION ( PROCEDURE_NAME = usp_ProcessNotification, MAX_QUEUE_READERS = 1, EXECUTE AS OWNER ); GO -- crete the notofication service for our queue with the pre-defined message type CREATE SERVICE DeadLockNotificationsService ON QUEUE DeadLockNotificationsQueue ([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]); GO -- create the route for the service CREATE ROUTE DeadLockNotificationsRoute WITH SERVICE_NAME = 'DeadLockNotificationsService', ADDRESS = 'LOCAL'; GO -- create the event notification for the DEADLOCK_GRAPH event. -- other lock events can be added -- DROP EVENT NOTIFICATION DeadLockNotificationEvent ON SERVER CREATE EVENT NOTIFICATION DeadLockNotificationEvent ON SERVER FOR DEADLOCK_GRAPH -- , LOCK_DEADLOCK_CHAIN, LOCK_DEADLOCK, LOCK_ESCALATION -- ANY OF these can be SET TO SERVICE 'DeadLockNotificationsService', 'current database' -- CASE sensitive string that specifies USE OF server broker IN CURRENT db GO -- check to see if the event notification has been created ok SELECT * FROM sys.server_event_notifications WHERE name = 'DeadLockNotificationEvent'; GO