En utilisant sp_whoisactive, je vois que j'ai beaucoup de processus dans un statut "dormant", plusieurs heures pendant des heures. Je ne suis pas sûr de la cause et je suis toujours dépannage (délai d'attente? Bad code avec transaction non engagée?).
En utilisant la requête ci-dessous, j'ai remarqué que toutes ces transactions ouvertes sont des requêtes SELECT dans un état "Dormeur". Pourquoi un choix peut-il ouvrir une transaction? Pourraient-ils être au milieu d'une procédure stockée quelque part et que le champ [Text] indique uniquement la dernière déclaration de la procédure qui a été exécutée? Il n'y a pas de wait_info sur aucune des transactions ouvertes.
SELECT [TEXT] as SQLcode
FROM SYS.SYSPROCESSES SP
CROSS APPLY SYS.DM_EXEC_SQL_TEXT(SP.[SQL_HANDLE])AS DEST WHERE OPEN_TRAN=1
Dormir n'est pas nécessairement un problème. Selon l'application, la mise en commun du fil peut maintenir la connexion ouverte même si rien ne fonctionne.
S'il n'y a pas de transactions ouvertes, alors c'est vraiment un problème?
Kendra Little a écrit à ce sujet récemment sur son blog :
Les dormeurs sont généralement ok
Une session de sommeil sans transaction ouverte ...
Tenir des serrures sur une table
Utilise très peu de ressources
Peut être réutilisé par l'application (par quelque chose comme la mise en commun de la connexion)
Selon la suggestion de Kenda, examinez SP_WhoisActif au lieu d'utiliser SP_WHO2.
qu'en est-il de commencer à utiliser cette requête ci-dessous, puis sur mesure pour vos propres objectifs:
select *
from sys.dm_tran_database_transactions t
join sys.dm_tran_session_transactions st on t.transaction_id = st.transaction_id
join sys.dm_exec_sessions s on s.session_id = st.session_id
join sys.dm_exec_connections c on c.session_id = s.session_id
cross apply sys.dm_exec_sql_text(most_recent_sql_handle)
where 1=1
and text <> 'begin tran'
and text not like '%sp_MS%'
and datediff(minute, last_request_end_time, getdate()) > 60
and database_transaction_begin_time is not null
J'utilise celui-ci ci-dessous, cela aide dans la plupart des cas:
SELECT
es.session_id AS session_id
,CASE WHEN eS.LOGIN_NAME = eS.ORIGINAL_LOGIN_NAME
THEN eS.LOGIN_NAME
ELSE eS.LOGIN_NAME + ' (' + eS.ORIGINAL_LOGIN_NAME + ')'
END AS LOGIN_NAME
,es.Host_name AS hostname
,es.status
,es.last_request_start_time
,es.last_request_end_time
,es.CPU_TIME AS CPU_TIME_MS
,es.MEMORY_USAGE AS MEMORY_USAGE_PAGES
,es.ROW_COUNT
,NULL AS blocked_by
,NULL AS waittype
,NULL AS waittime
,NULL AS lastwaittype
,NULL AS waitresource
,dbid=trans.database_name
,NULL as cmd
,t.text AS [QUERY]
,NULL AS PARENT_QUERY
,TRANSACTION_ISOLATION_LEVEL = NULL
,NULL as cpu
,NULL AS physical_io
--,es.open_transaction_count as [open_tran]
,es.program_name
--,es.login_time
--,ota.task_state
--,ota.pending_io_count
--,ota.pending_io_byte_count
FROM sys.dm_exec_sessions AS es
INNER JOIN sys.dm_exec_connections AS c
ON es.session_id = c.session_id
--LEFT OUTER JOIN sys.dm_os_tasks ota ON es.session_id = ota.session_id
CROSS APPLY (
SELECT MAX(DB_NAME(dt.database_id)) AS database_name
FROM sys.dm_tran_session_transactions AS st
INNER JOIN sys.dm_tran_database_transactions AS dt
ON st.transaction_id = dt.transaction_id
WHERE is_user_transaction = 1
GROUP BY st.session_id
HAVING es.session_id = st.session_id
) AS trans
CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) AS t
WHERE es.session_id NOT IN (
SELECT session_id
FROM sys.dm_exec_requests
)
AND es.session_id IN (
SELECT request_session_id
FROM sys.dm_tran_locks
WHERE request_status = 'GRANT'
)
AND STATUS = 'sleeping'
AND is_user_process = 1
AND es.session_id <> @@spid
S'il vous plaît éviter d'utiliser SYS.SYSPROCESSES