下午好,
XML架构验证代码段在开发/ q& a环境中正常运行,但在Production中产生了一些奇怪的验证结果。通常的怀疑是代码对于线程是不安全的,并且生产方案的额外负载正在消除错误。
具体情况如下。请考虑验证的XML是:
<mssql:spExecute type="ResultSet" xmlns:mssql="urn:namespace">
<mssql:actor>IPASS</mssql:actor>
<mssql:connection>ConnectionString</mssql:connection>
<mssql:storedProcedure>dbo.RedFox</mssql:storedProcedure>
</mssql:spExecute>
在一整天的过程中,大约300次执行(> 2M)会产生以下异常:
System.Xml.Schema.XmlSchemaValidationException The 'http://www.w3.org/2000/xmlns/:mssql' attribute is not declared.
架构验证器似乎抱怨名称空间声明。
代码结构如下:
有关可能导致验证通过命名空间声明阻塞的内容的任何想法吗?
答案 0 :(得分:4)
您所描述的是受控实验的结果或 从生产环境观察? 如果是后者,请尝试在受控设置中重现它以确保其他一些 错误不是一个真正的原因。
The documentation for XmlSchemaSet
说:
“不保证任何实例成员都是线程安全的。”
这包括属性读取和“只读”方法。
所以我们不能假设XmlSchemaSet
的只读使用是线程安全的。
直到Microsoft提供明确允许共享相同编译的实现
线程之间的架构表示,唯一安全的做法就是不共享。
OTOH分享单个编译的不可变XmlSchemaSet
来验证是合乎逻辑的
多个XmlDocument
(或XmlReader
)个实例。
这是一个非常明智的场景,所以我不明白为什么它没有明确
允许并记录在案。
(更新:显然Java's standard XML library明确保证这一点。 为什么在.NET中不是这样?)
答案 1 :(得分:2)
这可以在.NET 4.0中修复,但不记录。
我在生产网络服务中遇到了同样的错误。错误类似,并且在峰值活动期间是随机的:“ xxx元素未声明”。但是在我的例子中,我们只是使用循环读取命令来验证XML,而不是序列化对象。
该服务是在.NET 3.5下构建/运行的,在开发环境中,我可以通过启动5个线程并同时进行服务调用来轻松复制此错误。该错误大约发生在10个请求中。
当我坐下来解决这个问题时,我做的第一件事就是将服务升级到.NET 4.0。一旦我这样做,我就不能再产生这个错误了。我增加了线程数并删除了服务限制 - 仍然没有错误。
虽然当前的文档仍然表明XmlSchema实例操作不能保证线程安全,但似乎在3.5和4.0之间进行了一些框架更改,这提高了XmlSchema上读/验证类型操作的线程安全性。
答案 2 :(得分:1)
我遇到了同样的问题。似乎XML验证不是只读操作,本文指出:
http://blogs.msdn.com/xmlteam/archive/2009/04/27/xmlschemaset-thread-safety.aspx
锁定它解决了我的问题。