Our high volume native (C++) data processing application is experiencing intermittent dysfunction in one or more ODBC data access threads when reading or writing a BLOB from a table, and in particular experiences dysfunction in the ODBC connection
in use by one or more threads when the problem occurs.
The SQL State returned by ODBC (GetDiagRec) is 08S01, which according to documentation is an indication of SQL connection dysfunction.
[Microsoft][ODBC Driver 13 for SQL Server] The connection is no longer usable because the server response for a previously executed statement was incorrectly
formatted
We don't think the information we are collecting in association with this SQL State and the connection failure is indicative of the true nature of the problem. In our native service applications, we are configuring a shared ODBC environment with a
per-driver connection pool. As near as I can determine from documentation, this means we have one connection pool shared by all data access threads per service application (per-process), because there is only one driver in use.
We have concerns that we may be responsible for this failure by calling SQLEndTran with SQL_ROLLBACK on a connection handle in this shared environment in our data access threads, when a BLOB read failure occurs, leading to the SQLEndTran call. Specifically,
we have concerns about what the following ODBC documentation really means:
Note
SQLEndTran cannot be used to commit or roll back transactions
on a shared environment. SQLSTATE HY092 (Invalid attribute/option identifier) will be returned if SQLEndTran is called with Handle set to either the handle of a shared environment or the handle of a connection
on a shared environment.
What this documentation seems to imply is that manual commit transactions are not supported on pooled ODBC connections and bad things will happen if you call SQLEndTran on these connection handles. This is a very big deal.
Our code is doing exactly what is described here - calling SQLEndTran on a connection handle in a shared environment. However, we do not see SQLSTATE HY092 when the problem occurs and a pool connection appears to die. Instead, we see 08S01. In addition, we do not encounter SQL_ERROR when we call SQLEndTran with SQL_COMMIT on any connection handle in any of the hundreds of thousands of successful BLOB read and write calls we make each day. So it would appear to us that SQLEndTran with
SQL_COMMIT on a connection handle in a shared environment may be benign, whereas SQLEndTran with SQL_ROLLBACK may not be benign, and may kill the pool connection.
We also have irrefutable evidence that one or more connections in our shared environment pool remain dysfunctional after each 08S01, and cause thousands of repeated data access failures as they are (apparently) served up by the driver manager in subsequent
calls in data access threads.
Could someone please comment on, or explain the ODBC documentation note shown above, and on its potential relation to our problem?
Thanks in advance...