.NET Core应用中SQLTableDependency某表更新无通知,增删正常
1. 检查订阅时的监听字段配置
SQLTableDependency默认会监听全表字段,但如果显式指定了部分列,更新未被指定的字段就不会触发通知。核对你的订阅代码:
// 错误示例:仅监听Name列,更新Age不会触发通知 var dependency = new SqlTableDependency<YourEntity>(connStr, "AbnormalTable", includeOldValues: true, nameof(YourEntity.Name)); // 正确处理:要么不指定列(监听全表),要么包含所有需监听的字段 var dependency = new SqlTableDependency<YourEntity>(connStr, "AbnormalTable", includeOldValues: true); // 或指定多列 var dependency = new SqlTableDependency<YourEntity>(connStr, "AbnormalTable", includeOldValues: true, nameof(YourEntity.Name), nameof(YourEntity.Age));
2. 验证实体类与数据库表的字段映射
确保实体类属性和数据库表字段完全匹配,包括名称(注意大小写匹配,SQL Server默认不区分,但严格映射场景可能出问题)、数据类型。比如实体类用UserAge但数据库是Age,需添加[Column("Age")]特性,否则SQLTableDependency无法识别字段更新。
3. 检查SQLTableDependency版本与SQL Server兼容性
不同版本的SQLTableDependency对SQL Server版本支持有差异,若使用SQL Server 2019+但依赖包版本过旧,可能存在兼容性问题。尝试升级SQLTableDependency到最新稳定版。
4. 确认数据库Service Broker状态
SQLTableDependency依赖SQL Server的Service Broker,检查目标数据库的Broker是否启用:
SELECT name, is_broker_enabled FROM sys.databases WHERE name = 'YourDbName';
若is_broker_enabled为0,执行以下语句启用:
ALTER DATABASE YourDbName SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE;
5. 对比异常表与正常表的触发器逻辑
虽然触发器能打印内容,但要确认是否正确调用了SQLTableDependency的队列存储过程。正常的更新触发器应包含EXEC [SqlTableDependency_XXX_XXX_OnUpdate] ...这类语句,将异常表的触发器代码和正常表对比,排查是否存在逻辑差异。
6. 检查应用端事件处理逻辑
确认OnChanged事件的处理代码没有过滤ChangeType.Update类型的通知:
// 错误示例:仅处理新增和删除 dependency.OnChanged += (sender, e) => { if (e.ChangeType != ChangeType.Insert && e.ChangeType != ChangeType.Delete) return; // 业务逻辑 }; // 正确处理:包含更新类型 dependency.OnChanged += (sender, e) => { switch(e.ChangeType) { case ChangeType.Insert: // 处理新增 break; case ChangeType.Update: // 处理更新 break; case ChangeType.Delete: // 处理删除 break; } };
7. 排查SQL Server队列与服务状态
SQLTableDependency会生成对应队列和服务,检查异常表的队列是否堆积消息或状态异常:
-- 查询队列状态 SELECT name, is_receive_enabled, is_enqueue_enabled FROM sys.service_queues WHERE name LIKE '%SqlTableDependency%AbnormalTableName%'; -- 查询未处理的消息数 SELECT COUNT(*) FROM sys.transmission_queue WHERE service_name LIKE '%SqlTableDependency%AbnormalTableName%';
若队列有未处理消息,可删除对应队列和服务后重启应用,让SQLTableDependency重新生成。
内容的提问来源于stack exchange,提问作者Ummar

