N
Nick
Who can prove that the following cannot happen:
1. client A gets an ADO.Net/SqlClient connection from the connection pool
2. client A fires a TSQL batch (select a,b,c from x) at Sql Server 2K5
3. Sql Server goes to work but the are some locked resources
4. ADO.Net loses patience and times out on Connection.CommandTimeout and
throws an exception to the client
5. client A catches the exception, "closes" the connection, thus returning
it to the pool
6. client B now gets handed the the same connection from the pool, for which
the pool fires an sp_reset_connection over that connection
8. the sp_reset_connection command gets queued and the supposedly clean
connection gets handed to client B
9. client B fires its TSQL batch (select d,e,f from z) at the connection and
awaits results
we now have the following situation on that one same connection:
-Sql Server is still busy with client A's TSQL batch
-after which it will execute the queued sp_reset
-after which it will get round to client B's TSQL batch
what if now the following occurs:
10. Sql Server finally finishes client A's TSQL batch and signals the
connection that there are results to be fetched.
11. ADO.Net receives that signal and consumes the results and passes them to
the awaiting client
12. The client, expecting results (d,e,f) instead receives (a,b,c)
Pretty ugly huh?
I'm not certain of my speculations on the exact proceedings of the first 11
steps, but we certainly see step 12.
Is it by design that this the default behaviour of ADO.Net connection
pooling? Or is it documented somewhere that a command.timeout exception
should be handled in some way to avoid this happening?
1. client A gets an ADO.Net/SqlClient connection from the connection pool
2. client A fires a TSQL batch (select a,b,c from x) at Sql Server 2K5
3. Sql Server goes to work but the are some locked resources
4. ADO.Net loses patience and times out on Connection.CommandTimeout and
throws an exception to the client
5. client A catches the exception, "closes" the connection, thus returning
it to the pool
6. client B now gets handed the the same connection from the pool, for which
the pool fires an sp_reset_connection over that connection
8. the sp_reset_connection command gets queued and the supposedly clean
connection gets handed to client B
9. client B fires its TSQL batch (select d,e,f from z) at the connection and
awaits results
we now have the following situation on that one same connection:
-Sql Server is still busy with client A's TSQL batch
-after which it will execute the queued sp_reset
-after which it will get round to client B's TSQL batch
what if now the following occurs:
10. Sql Server finally finishes client A's TSQL batch and signals the
connection that there are results to be fetched.
11. ADO.Net receives that signal and consumes the results and passes them to
the awaiting client
12. The client, expecting results (d,e,f) instead receives (a,b,c)
Pretty ugly huh?
I'm not certain of my speculations on the exact proceedings of the first 11
steps, but we certainly see step 12.
Is it by design that this the default behaviour of ADO.Net connection
pooling? Or is it documented somewhere that a command.timeout exception
should be handled in some way to avoid this happening?