【问题标题】:How to make sure sp_xml_removedocument is always run如何确保 sp_xml_removedocument 始终运行
【发布时间】:2020-12-28 04:46:37
【问题描述】:

我想运行一个查询来释放由sp_xml_preparedocument 创建的 XML 解析所占用的空间,然后会话被终止。我的代码是这样的:

DECLARE @idoc INT, @result XML

SELECT @result = Result
FROM XmlFieldTable

EXEC sp_xml_preparedocument @idoc OUTPUT, @result

-- some query in the middle

EXEC sp_xml_removedocument @idoc;

我想确保在会话被杀死之前删除句柄,否则内部缓存可能会溢出,我该怎么办?

我已经尝试使用 try/catch 语句或事务,但没有帮助。

【问题讨论】:

  • XML 的哪个空间?哪个把手?为什么会话会在事务不回滚的情况下被终止? @idoc 代表什么?
  • @Charlieface 抱歉,我已经更新了内容。根据Microsoft Document,sp_xml_preparedocument 将使用服务器的内部缓存来存储已解析的 XML。您也可以查看my question了解更多信息。
  • 我建议使用内置的 XQuery 支持,而不是使用这种带有大量已知内存泄漏和问题的旧代码......
  • @marc_s 感谢您的推荐,但在某些情况下,openxmlXquery 快得多,您可以查看this answer 了解更多信息。

标签: sql-server tsql


【解决方案1】:

我原以为它会在事务出错时回滚句柄。至少根据docs 看来,该句柄仅对单个会话有效。但如果它不起作用,我建议您将其报告为 Azure Feedback 上的错误。从here 看来,其他人也有同样的问题。

作为一种解决方法,在客户端捕获错误并检查打开的句柄:

SELECT document_id FROM dm_exec_xml_handles (@@spid)

遍历结果并传递给sp_xml_removedocument

您可能希望定期关闭所有句柄,即使对于其他会话也是如此,因为整个连接可能会关闭。所以将 0 传递给函数。您可以定期作为代理作业执行此操作。

【讨论】:

  • 如果会话被杀死或查询被取消(例如客户端查询超时),执行批处理中的任何代码都不会执行,包括try/catch。
  • @DanGuzman 我知道。但是交易应该可以解决问题。如果句柄只对会话有效,那么它应该在会话结束时关闭句柄。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-05
  • 2017-05-29
  • 2013-05-09
  • 2023-02-26
  • 2020-08-19
  • 2021-01-24
相关资源
最近更新 更多