Found this thread researching a similar problem. I came up with the following sql as a good way to debug leaky connections in SQL Server:
SELECT S.spid, login_time, last_batch, status, hostname, program_name, cmd,
(
select text from sys.dm_exec_sql_text(S.sql_handle)
) as last_sql
FROM sys.sysprocesses S
where dbid > 0
and DB_NAME(dbid) = '<my_database_name>'
and loginame = '<my_application_login>'
order by last_batch asc
What this gives you is all open connections on a particular database and login, along with the last sql executed on that connection, sorted by the time at which that sql was executed.
Because of connection pooling, you can’t just rely on the fact that there are a lot of connections hanging around to tell you that you have a connection leakage, because connection pooling will keep connections around even if they are closed correctly from code. However, if you do have a connection leakage, what you will see is that some connections become “frozen”—they will show up in the above query and the “last_batch” timestamp will never change. The other connections will also hang around, but every time new sql is run on them, the “last_batch” timestamp gets updated. So the effect is that the frozen connections will float to the top of this query.
If you have the source code of the application in question, the fact that this gives you the last sql executed on the orphaned connection is very valuable for debugging.
Note The spelling mistake with 'loginame' (missing 'n') is in the sys.sysprocesses
view. The statement above is correct.
loginame nchar(128) Login name.
https://docs.microsoft.com/en-us/sql/relational-databases/system-compatibility-views/sys-sysprocesses-transact-sql?view=sql-server-ver15
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…