0

0

事件通知(EventNotification)实践

php中文网

php中文网

发布时间:2016-06-07 14:55:42

|

1362人浏览过

|

来源于php中文网

原创

事件通知(Event Notification )实践 问题描述 作为DBA,我们常常需要在SQL Server实例或数据库级别上跟踪正在发生的事件。有没有方法跟踪这些修改而不会太影响SQL Server性能呢? 解决方案 SQL Server 2005及其以后版本提供了事件通知(Event Notification

事件通知(Event Notification)实践

 

华友协同办公自动化OA系统
华友协同办公自动化OA系统

华友协同办公管理系统(华友OA),基于微软最新的.net 2.0平台和SQL Server数据库,集成强大的Ajax技术,采用多层分布式架构,实现统一办公平台,功能强大、价格便宜,是适用于企事业单位的通用型网络协同办公系统。 系统秉承协同办公的思想,集成即时通讯、日记管理、通知管理、邮件管理、新闻、考勤管理、短信管理、个人文件柜、日程安排、工作计划、工作日清、通讯录、公文流转、论坛、在线调查、

下载

问题描述

作为DBA,我们常常需要在SQL Server实例或数据库级别上跟踪正在发生的事件。有没有方法跟踪这些修改而不会太影响SQL Server性能呢?

 

解决方案

SQL Server 2005及其以后版本提供了事件通知(Event Notification)机制,来跟踪发生在数据库或实例级别上的事件或修改。这其实也可以通过DDL触发器或这SQL跟踪来实现,但是事件通知有异步相应事件和运行在事务范围之外的优点,因此能作为数据库应用程序的一部分,捕获预定义的事件,而无需占用分配给事务的资源。

 

事件通知是一个使用DDL触发器或SQL跟踪的可编程的替代方案,执行相应不同的DDL语句、SQL跟踪、Service Broker事件(像QUEUE_ACTIVATION或BROKER_QUEUE_DISABLED),然后以XML格式发送信息到SQL Server Service Broker服务。换句话说,当创建一个通知,SQL Server跟踪预定义的事件,并将发生的事件写入到SSB服务,然后异步地从SSB队列接收信息。

 

步骤一:

首先检查Service Broker是否在数据库级别被启用,如果没有,启用它。然后创建一个SSB队列,SSB服务将会用这个队列去存储消息到服务。该服务使用内置的契约(契约定义了一个能发送到SSB服务的消息类型),http://schemas.microsoft.com/SQL/Notifications/PostEventNotification,专用于事件通知(Event Notification)。注意:你需要排他访问数据去执行修改数据库命令。

 

--Check if the database is enabled for Service Broker
--If not then enable it
IF EXISTS (SELECT * FROM sys.databases WHERE name = 'AdventureWorks2012'
AND is_broker_enabled = 0)
ALTER DATABASE AdventureWorks2012 SET ENABLE_BROKER;
GO
USE AdventureWorks2012
GO
--Create a queue which will hold the tracked information
CREATE QUEUE dbo.EventNotificationQueue
GO
--Check if the queue is created or not
SELECT * FROM sys.service_queues
WHERE name = 'EventNotificationQueue'
GO
--Create a service on which tracked information will be sent
CREATE SERVICE [//AdventureWorks2012/EventNotificationService]
ON QUEUE dbo.EventNotificationQueue
([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification])
GO
--Check if the service is created or not
SELECT * FROM sys.services
WHERE name = '//AdventureWorks2012/EventNotificationService'
GO

 

步骤二:

创建两个数据库级别的通知。首先,当有一个创建表命令执行时,将发出通知;然后,当有一个修改表命令执行时,将发出通知。也可以创建一个通知事件组;例如,你可以创建一个单一的通知DDL_TABLE_EVENTS去跟踪像创建、修改、删除表的所有事件。

 

--Create a notification to track create table command
CREATE EVENT NOTIFICATION NotifyCREATETABLEEvents
ON DATABASE
FOR CREATE_TABLE
TO SERVICE '//AdventureWorks2012/EventNotificationService' , 'current database'
GO
--Create a notification to track alter table command
CREATE EVENT NOTIFICATION NotifyALTERTABLEEvents
ON DATABASE
FOR ALTER_TABLE
TO SERVICE '//AdventureWorks2012/EventNotificationService' , 'current database'
GO
--Check if both the above notifications created or not
SELECT * FROM sys.event_notifications
WHERE name IN ('NotifyCREATETABLEEvents','NotifyALTERTABLEEvents')
GO

 

步骤三:

创建一个服务器级别的通知,当一个错误在SQL Server实例级别触发时,该通知即被触发。可以查看sys.server_event_notifications目录视图查看通知是否存在于该服务器上。

 

--Create a notification to error occuring at server level
CREATE EVENT NOTIFICATION NotifyERROREvents
ON SERVER WITH FAN_IN
FOR ERRORLOG
TO SERVICE '//AdventureWorks2012/EventNotificationService', 'current database'
GO
--Check if the above notification was created or not
SELECT * FROM sys.server_event_notifications
WHERE name IN ('NotifyERROREvents')
GO

 

步骤四:

验证刚才建立的事件通知是否在正常工作。在这个脚本里,先创建一个表,然后修改它,它将会被数据库级别的事件通知捕获到,并且我使用了RAISERROR(WITH LOG从句需要被服务器级别事件通知捕获)在SQL Server里触发一个错误,该错误将会被上一个服务器级别的事件通知捕获到。

 

--Generate a create table event
CREATE TABLE ABC
(
COL1 INT,
COL2 INT
)
GO
--Generate an alter table event
ALTER TABLE ABC
ADD COL3 INT
GO
--Generate a server level event
RAISERROR (N'Generating error for Event Notification testing...', 16, 1)
WITH LOG
GO
--Review if the events were tracked in queue
SELECT CAST(message_body AS XML) AS message_in_xml
FROM dbo.EventNotificationQueue
GO

 

步骤五:

事件通知以XML格式发送捕获到的信息到SSB服务;可以查询队列去看到捕获的信息,但是你需要用RECEIVE命令从队列接收消息,如下所示,处理它们并从队列中移除。使用RECEIVE命令你可以设置在一次接受的记录的数量。在这个脚本中,我使用TOP (1)命令接受第一行队列中的消息,并显示它的内容。事件通知以XML格式发送消息(注意:我们使用创建服务的内置契约,它定义了只有XML数据能被写入到服务),因此我转换消息体到XML数据类型。因为我使用了TOP (1)从句在RECEIVE命令,因为队列中有3条记录,我运行了下面的命令3次。查询的结果如下图。也可以使用一个循环的结构去从队列读取所有的记录,而不用运行这个脚本多次。

 

DECLARE @TargetDialogHandle UNIQUEIDENTIFIER;
DECLARE @EventMessage XML;
DECLARE @EventMessageTypeName sysname;
WAITFOR
( RECEIVE TOP(1)
@TargetDialogHandle = conversation_handle,
@EventMessage = CONVERT(XML, message_body),
@EventMessageTypeName = message_type_name
FROM dbo.EventNotificationQueue
), TIMEOUT 1000;
SELECT @TargetDialogHandle AS DialogHandle, @EventMessageTypeName AS MessageTypeName,
@EventMessage.value('(/EVENT_INSTANCE/EventType)[1]', 'varchar(128)' ) as EventType,
@EventMessage.value('(/EVENT_INSTANCE/ServerName)[1]', 'varchar(128)' ) as ServerName,
@EventMessage.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(128)' ) as DatabaseName,
@EventMessage.value('(/EVENT_INSTANCE/LoginName)[1]', 'varchar(128)' ) as LoginName,
@EventMessage.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)') AS TSQLCommand,
@EventMessage.value('(/EVENT_INSTANCE/TextData)[1]', 'varchar(128)' ) AS TextData,
@EventMessage.value('(/EVENT_INSTANCE/Severity)[1]', 'varchar(128)' ) AS Severity,
@EventMessage.value('(/EVENT_INSTANCE/Error)[1]', 'varchar(128)' ) AS ErrorNumber

 

clip_image001

clip_image002

clip_image003

 

步骤六:

下面的代码可以清理并删除所有的对象,以创建的相反顺序。

 

DROP EVENT NOTIFICATION NotifyCREATETABLEEvents ON DATABASE
GO
DROP EVENT NOTIFICATION NotifyALTERTABLEEvents ON DATABASE
GO
DROP EVENT NOTIFICATION NotifyERROREvents ON SERVER
GO
DROP TABLE ABC
GO
DROP SERVICE [//AdventureWorks2012/EventNotificationService]
GO
DROP QUEUE dbo.EventNotificationQueue
GO

 

权限需求:

1. 为了创建一个数据库级别的事件通知,需要在该数据库有CREATE DATABASE DDL EVENT NOTIFICATION权限。为了删除它,你必需是该事件通知的拥有者,或者在该数据库有ALTER ANY DATABASE EVENT NOTIFICATION权限。

 

2. 为了创建服务器级别的通知,你需要有CREATE DDL EVENT NOTIFICATION权限。为了删除它,你必需是该事件通知的拥有者,或者在该服务器有ALTER ANY EVENT NOTIFICATION权限。

 

3. 为了创建事件通知捕获SQL跟踪,你需要在该服务器有CREATE TRACE EVENT NOTIFICATION权限。为了删除它,你必需是该事件通知的拥有者,或者有ALTER ANY EVENT NOTIFICATION权限。

 

4. 为了创建队列范围的事件通知,你需要有该队列的ALTER权限。为了删除它,你必需是该事件通知的拥有者,或者有该队列的ALTER权限。

 

备注:

1. 你可以查询sys.event_notification_event_types获取所有可以创建事件通知的事件的列表,也可以查看DDL事件,DDL事件组,SQL跟踪事件,SQL跟踪事件组。

 

2. 去查看事件通知和触发器之间的不同,可以访问这里;事件通知和SQL跟踪的不同,可以访问这里。

 

3. 你不能直接修改一个通知,你需要删除并重建它。



热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

16

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

23

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

75

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

95

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

218

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

420

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

168

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

222

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

33

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 4.2万人学习

Django 教程
Django 教程

共28课时 | 4.9万人学习

React 教程
React 教程

共58课时 | 6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号