CREATE XML SCHEMA COLLECTION静默失败致后续脚本异常的原因问询
是的,这种情况完全有可能发生——不过并不是XML架构集合创建失败(毕竟重试就能成功),而是架构已经创建成功,但由于SQL Server元数据处理的边缘情况,后续的建表脚本暂时看不到它。
问题背后的原因
最可能的几个诱因:
- 元数据视图同步延迟:SQL Server的系统目录视图(比如
sys.xml_schema_collections)并不总是即时反映DDL变更,尤其是服务器负载较高的时候。虽然通常同一个连接应该能立即看到自己执行的DDL修改,但罕见的竞争条件或元数据缓存刷新延迟,可能会导致短暂的“架构已存在但查询不到”的窗口。 - 隐式事务提交延迟:部分DDL操作(包括
CREATE XML SCHEMA COLLECTION)会在隐式事务中执行。即便ExecuteNonQuery()成功返回,事务完全提交并将元数据变更同步到所有系统组件可能存在微小延迟。 - 连接级元数据缓存:你封装的
DbConnection可能为了性能缓存了元数据。虽然SQL Server通常会在DDL变更后失效这个缓存,但偶尔的小故障会让旧的元数据残留,导致下一个命令看不到新创建的架构。
验证与解决方法
既然重试能解决问题,修复思路就是确保架构存在且可见后再执行建表脚本:
- 添加显式验证:执行完XML架构脚本后,运行查询检查架构是否存在:
循环重试这个查询(每次间隔100ms左右),直到返回结果,再执行建表脚本。SELECT 1 FROM sys.xml_schema_collections WHERE name = 'xmlFoo' - 拆分命令并添加延迟:把XML架构脚本和建表脚本拆成单独的
DbCommand实例执行,中间插入一段短暂的人工延迟(比如Thread.Sleep(100)),给SQL Server留出元数据同步的时间。 - 强制刷新元数据:可以执行
DBCC FREEPROCCACHE(不过这会影响整个服务器,谨慎使用)或EXEC sp_refreshsqlmodule来显式刷新连接的元数据缓存。更安全的做法是为建表脚本新开一个连接,新连接会获取最新的元数据。
关键提示
不太可能出现XML架构创建失败但ExecuteNonQuery()不报错的情况——SQL Server如果执行CREATE XML SCHEMA COLLECTION失败,通常会立即抛出异常。重试成功也证明架构是有效的,最终能创建成功;问题只是出在时机和元数据可见性上。
内容的提问来源于stack exchange,提问作者Andrew Cooper
相关产品推荐
相关产品推荐

