mike 57299 (2/27/2014)
Hi.This is a great function. Can you tell me if the system uses one database file for this function? I have created separate databases for each client. If I run the sp_exec from each database, will they go to separate queues or one queue?
Thanks,
Mike
The system only uses one database called pmaster.
Each sp_exec_init call will create a queue per that connection, and all sp_exec's after that and within the same connection will queue the query to that queue, the sp_exec_end call will drop that queue and clean up. Internally each queued query will use a new spid to run.
It's allowed to have multiple connections, and within each of those connections you may run a pair of sp_exec_i nit and sp_exec_end. They won’t interrupt each other.
Within one connection (or one sql script), I only expect one level of sp_exec_init and sp_exec_end pair, so do not make nested calls directly. However, you may still sp_exec a string of statements including sp_exec_init and sp_exec_end pair, and it will be run in another spid and start a whole isolated world. Personally I have not run scenario like that.
This is a view that I use to monitor the queues --
USE [pmaster]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE view [dbo].[vw_exec_state] as
select m.master_spid,m.worker_num,s.*
from dbo.exec_master m
cross apply(
select COUNT(1) [queued]
,SUM(CASE when worker_start_time is not null then 1 else 0 END) [started]
,SUM(CASE when worker_end_time is not null then 1 else 0 END) [finished]
,SUM(CASE when (worker_start_time is not null) and (worker_end_time is null) then 1 else 0 END) [running]
,SUM(CASE return_code when 0 then 1 else 0 END) [success]
,lower(dbo.convert_seconds(DATEDIFF(SECOND,MIN(q.create_time),GETDATE()))) [duration]
,MAX(q.exec_queue_id) max_queue_id
from dbo.exec_queue q where q.master_spid = m.master_spid
) s
GO
Sometimes you may lose the connection before calling the sp_exec_end, or you chose not to call sp_exec_end so that you may check status later. This proc allow you to drop and cleanup a queue that was created in another connection --
USE [pmaster]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE procedure [dbo].[p_exec_end2]
@master_spid smallint = null
,@wait bit = 1
as
set nocount on
if (@master_spid is null) set @master_spid=@@SPID
if @wait=1
while exists(select * from dbo.exec_queue where master_spid=@master_spid and worker_spid is null)
waitfor delay '00:00:03';
begin try
begin transaction;
exec dbo._p_exec_clean @master_spid,'';
commit transaction;
end try
begin catch
exec dbo.p_printerror;
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
return Error_number();
end catch
exec dbo.p_exec_cleanqueue;
return @@error
GO