Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Schema validation error / Thread safety of XmlSchemaSet?

Good afternoon,

An XML schema validation snippet is working fine on development/q&a environments, but is yielding some odd validation results in Production. The usual suspect would be that the code is unsafe for threading, and that the additional load of the Production scenario is flushing out the error.

The exact scenario is as follows. Consider that the XML being validated is:

<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>

In the course of a full day, around 300 executions (of >2M) will yield the following exception:

System.Xml.Schema.XmlSchemaValidationException
The 'http://www.w3.org/2000/xmlns/:mssql' attribute is not declared.

The schema validator seems to complain about the namespace declaration.

The code structure is as follows:

  • There is a static instance of XmlSchemaSet;
  • Initialization of the XmlSchemaSet instance is being done in a thread-safe manner;
  • Each worker thread makes use of the same XmlSchemaSet;
  • The validation occurs during an XmlSerializer.Deserialize() call, using an XmlReader with XmlReaderSettings initialized with ValidationType.Schema.

Any thoughts on what might be causing the validation to choke with the namespace declaration?

like image 277
Filipe Toscano Avatar asked Sep 28 '09 12:09

Filipe Toscano


2 Answers

  1. Is what you describe a result of a controlled experiment or an observation from production environment? If the latter, try reproducing it in a controlled setup to make sure some other bug is not a real cause.

  2. The documentation for XmlSchemaSet says:

    "Any instance members are not guaranteed to be thread safe."

    This includes property reads and "read-only" methods. So we cannot assume that read-only use of XmlSchemaSet would be thread safe. Until Microsoft provides implementation that explicitly allows sharing of the same compiled schema representation between threads, the only safe thing to do is not to share.

  3. OTOH it seems logical to share single compiled immutable XmlSchemaSet to validate multiple XmlDocument (or XmlReader) instances. It is a very sensible scenario, so I don't understand why it is not explicitly permitted and documented.

    (Update: Apparently this is explicitly guaranteed in Java's standard XML library. Why isn't it so in .NET?)

like image 199
Tomek Szpakowicz Avatar answered Oct 03 '22 06:10

Tomek Szpakowicz


This may be fixed in .NET 4.0, but not documented.

I encountered the same error in a production web service. The error is similar, and random during peak activity: "The xxx element is not declared". However in my case we are just validating the XML with a looped Read command, rather than serializing an object.

The service is built/running under .NET 3.5, and in a development environment I can easily replicate this error by launching 5 threads and simultaneously making a service call. The error occurs about 1 in 10 requests.

When I sat down to address this issue, the first thing I did was upgrade the service to .NET 4.0. As soon as I did this, I cannot produce this error any more. I increased the thread count and removed service throttling - still no errors.

While the current documentation still indicates that XmlSchema instance operations are not guaranteed thread safe, there appears to have been some framework change between 3.5 and 4.0 that improves the thread safety for read/validation type operations on XmlSchema.

like image 21
Mike Avatar answered Oct 03 '22 05:10

Mike