Service Broker Activation Deadlocking
I have implemented a (slightly) modified version of conversation recycling using conversation timers and stored procedure activation from http://rusanu.com/2007/05/03/recycling-conversations/ . However it appears that, occasionally, deadlocks occur
between the send and activated procedures on the conversation group/table. The main modification is that instead of having a column to represent the SPID in the table I am using an IdentifierType and Identifier value to identify the conversation. However I
am only using the defaults (@@SPID) so I don't think that should matter in this case.
For the send side I have:
CREATE PROCEDURE [dbo].[usp_SendMessage]
@endpointCode VARCHAR(255) = NULL,
@endpointGroup VARCHAR(255) = NULL,
@xmlPayload XML=NULL,
@binaryPayload VARBINARY(MAX)=NULL,
@varcharPayload VARCHAR(MAX)=NULL,
@identifier VARCHAR(50) = @@SPID,
@identifierType VARCHAR(50) = '@@SPID'
AS BEGIN
SET NOCOUNT ON
DECLARE @fromService SYSNAME,
@toService SYSNAME,
@onContract SYSNAME,
@messageType SYSNAME,
@conversationTimeout INT
SELECT @fromService = FromService
, @toService = ToService
, @onContract = OnContract
, @messageType = MessageType
, @conversationTimeout = ConversationTimeout
FROM dbo.ServiceBrokerEndpointConfig
WHERE GroupCode = @endpointGroup
IF @fromService IS NULL OR @toService IS NULL OR @onContract IS NULL OR @messageType IS NULL OR @conversationTimeout IS NULL
BEGIN
RAISERROR (
N'Failed to get endpoint config for GroupCode ''%s''.'
, 16, 1, @endpointGroup) WITH LOG;
RETURN;
END
DECLARE @SBDialog UNIQUEIDENTIFIER
DECLARE @Message XML
DECLARE @counter INT
DECLARE @error INT
DECLARE @handle UNIQUEIDENTIFIER;
DECLARE @NotNullCount INT = ((CASE WHEN @xmlPayload IS NULL THEN 0 ELSE 1 END)
+ (CASE WHEN @binaryPayload IS NULL THEN 0 ELSE 1 END)
+ (CASE WHEN @varcharPayload IS NULL THEN 0 ELSE 1 END))
IF @NotNullCount > 1
BEGIN
RAISERROR (
N'Failed to SEND because %i payload fields are filled in when no more than 1 is expected'
, 16, 1, @NotNullCount) WITH LOG;
RETURN;
END
SET @counter = 1
WHILE (1=1)
BEGIN
SET @handle = NULL
-- Seek an eligible conversation in [ServiceBrokerConversations]
-- We will hold an UPDLOCK on the composite primary key
SELECT @handle = Handle
FROM [ServiceBrokerConversations] WITH (UPDLOCK)
WHERE Identifier = @identifier
AND IdentifierType = @identifierType
AND FromService = @fromService
AND ToService = @toService
AND OnContract = @onContract;
IF @handle IS NULL
BEGIN
-- Need to start a new conversation for the current @Id
BEGIN DIALOG CONVERSATION @handle
FROM SERVICE @fromService
TO SERVICE @toService
ON CONTRACT @onContract
WITH ENCRYPTION = OFF;
-- Then the sender must listen on the
-- send queue for the http://schemas.microsoft.com/SQL/ServiceBroker/DialogTimer message type and
-- cleanup appropriately.
IF @conversationTimeout IS NOT NULL
BEGIN
BEGIN CONVERSATION TIMER (@handle) TIMEOUT = @conversationTimeout;
END
INSERT INTO [ServiceBrokerConversations]
(Identifier, IdentifierType, FromService, ToService, OnContract, Handle)
VALUES
(@identifier, @identifierType, @fromService, @toService, @onContract, @handle);
END;
IF @xmlPayload IS NOT NULL
BEGIN
-- Attempt to SEND on the associated conversation
;SEND ON CONVERSATION @handle
MESSAGE TYPE @messageType (@xmlPayload);
END ELSE IF @binaryPayload IS NOT NULL
BEGIN
;SEND ON CONVERSATION @handle
MESSAGE TYPE @messageType (@binaryPayload);
END ELSE BEGIN
;SEND ON CONVERSATION @handle
MESSAGE TYPE @messageType (@varcharPayload);
END
SELECT @error = @@ERROR;
IF @error = 0
BEGIN
-- Successful send, just exit the loop
BREAK;
END
SELECT @counter = @counter+1;
IF @counter > 10
BEGIN
-- We failed 10 times in a row, something must be broken
RAISERROR (
N'Failed to SEND on a conversation for more than 10 times. Error %i.'
, 16, 1, @error) WITH LOG;
BREAK;
END
-- Delete the associated conversation from the table and try again
DELETE FROM [ServiceBrokerConversations]
WHERE Handle = @handle;
SET @handle = NULL;
END
END
And for the activation on the initiator queue I have:
CREATE PROCEDURE [dbo].[usp_InitiatorQueueHandler]
AS
BEGIN
SET NOCOUNT ON
DECLARE @handle UNIQUEIDENTIFIER;
DECLARE @messageTypeName SYSNAME;
DECLARE @messageBody VARBINARY(MAX);
WHILE (1=1)
BEGIN
BEGIN TRAN;
;WAITFOR (RECEIVE TOP(1)
@handle = conversation_handle,
@messageTypeName = message_type_name,
@messageBody = message_body
FROM [InitiatorQueue]), TIMEOUT 5000;
IF (@@ROWCOUNT = 0)
BEGIN
COMMIT TRAN;
BREAK;
END
-- Call the base stored procedure to handle ending the conversation
EXEC dbo.usp_BrokerHandleInitiator @handle, @messageTypeName, @messageBody
COMMIT TRAN;
END
END
GO
ALTER QUEUE [InitiatorQueue]
WITH ACTIVATION (
STATUS=ON,
PROCEDURE_NAME=dbo.usp_InitiatorQueueHandler,
EXECUTE AS OWNER,
MAX_QUEUE_READERS=10
GO
CREATE PROCEDURE [dbo].[usp_BrokerHandleInitiator]
@handle UNIQUEIDENTIFIER,
@messageTypeName SYSNAME,
@messageBody VARBINARY(MAX)
AS
BEGIN
SET NOCOUNT ON
IF @handle IS NOT NULL
BEGIN
-- Delete the message from the [ServiceBrokerConversations] table
-- before sending the [EndOfStream] message. The order is
-- important to avoid deadlocks.
IF @messageTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/DialogTimer'
OR @messageTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
DELETE FROM [ServiceBrokerConversations]
WHERE [Handle] = @handle;
END
IF @messageTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/DialogTimer'
BEGIN
;SEND ON CONVERSATION @handle
MESSAGE TYPE [EndOfStream];
END
ELSE IF @messageTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @handle;
END
ELSE IF @messageTypeName = N'http://schemas.microsoft.com/SQL/ServiceBroker/Error'
BEGIN
END CONVERSATION @handle;
-- We could send a notification or store the error in a table for further inspection
DECLARE @error INT;
DECLARE @description NVARCHAR(4000);
WITH XMLNAMESPACES (N'http://schemas.microsoft.com/SQL/ServiceBroker/Error' AS ssb)
SELECT
@error = CAST(@messageBody AS XML).value(
'(//ssb:Error/ssb:Code)[1]', 'INT'),
@description = CAST(@messageBody AS XML).value(
'(//ssb:Error/ssb:Description)[1]', 'NVARCHAR(4000)')
-- Maybe log to audit log instead?
RAISERROR(N'Received error Code:%i Description:"%s"',
16, 1, @error, @description) WITH LOG;
END;
END
END
The deadlock XML is:
<deadlock>
<victim-list>
<victimProcess id="process807dbd0c8" />
</victim-list>
<process-list>
<process id="process807dbd0c8" taskpriority="0" logused="0" waitresource="METADATA: database_id = 21 CONVERSATION_GROUP($hash = 0xff26c7e1:0x478840de:0xd403bb)" waittime="2600" ownerId="8333217736" transactionname="GetDialogByHandle" lasttranstarted="2015-03-23T10:53:58.683" XDES="0x87f251c90" lockMode="X" schedulerid="2" kpid="7220" status="suspended" spid="110" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2015-03-23T10:53:58.683" lastbatchcompleted="2015-03-23T10:53:58.683" lastattention="1900-01-01T00:00:00.683" clientapp=".Net SqlClient Data Provider" hostname="COLFOQA2" hostpid="1436" loginname="dev" isolationlevel="read committed (2)" xactid="8333217704" currentdb="21" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="MYDB.dbo.usp_SendMessage" line="116" stmtstart="7540" stmtend="7696" sqlhandle="0x03001500aada77428391a0005da4000001000000000000000000000000000000000000000000000000000000">
SEND ON CONVERSATION @handle
MESSAGE TYPE @messageType (@xmlPayload); </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 21 Object Id = 1115151018] </inputbuf>
</process>
<process id="process869a5e558" taskpriority="0" logused="588" waitresource="KEY: 21:72057594039959552 (1f1ae6770d1b)" waittime="2600" ownerId="8333217730" transactionname="user_transaction" lasttranstarted="2015-03-23T10:53:58.683" XDES="0x3e28456a8" lockMode="U" schedulerid="4" kpid="6720" status="background" spid="22" sbid="0" ecid="0" priority="0" trancount="2">
<executionStack>
<frame procname="MYDB.dbo.usp_BrokerHandleInitiator" line="28" stmtstart="1996" stmtend="2144" sqlhandle="0x03001500f704cd06e691a0005da4000001000000000000000000000000000000000000000000000000000000">
DELETE FROM [ServiceBrokerConversations]
WHERE [Handle] = @handle; </frame>
<frame procname="MYDB.dbo.usp_InitiatorQueueHandler" line="29" stmtstart="1014" stmtend="1172" sqlhandle="0x03001500316f56101694a0005da4000001000000000000000000000000000000000000000000000000000000">
EXEC dbo.usp_BrokerHandleInitiator @handle, @messageTypeName, @messageBody </frame>
</executionStack>
<inputbuf>
</inputbuf>
</process>
</process-list>
<resource-list>
<metadatalock subresource="CONVERSATION_GROUP" classid="$hash = 0xff26c7e1:0x478840de:0xd403bb" dbid="21" id="lock54fdb1800" mode="X">
<owner-list>
<owner id="process869a5e558" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process807dbd0c8" mode="X" requestType="wait" />
</waiter-list>
</metadatalock>
<keylock hobtid="72057594039959552" dbid="21" objectname="MYDB.dbo.ServiceBrokerConversations" indexname="PK__ServiceB__877FDFD18DF079BD" id="lock6c65b1a00" mode="U" associatedObjectId="72057594039959552">
<owner-list>
<owner id="process807dbd0c8" mode="U" />
</owner-list>
<waiter-list>
<waiter id="process869a5e558" mode="U" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
</deadlock>
I have a clustered index on the fields I am SELECTing by and a UNIQUE index on the Handle (for the DELETE). When running the SELECT/DELETE statements against the table the query plan reports index seeks are being used:
CREATE TABLE [dbo].[ServiceBrokerConversations] (
[Identifier] VARCHAR (50) NOT NULL,
[IdentifierType] VARCHAR (50) NOT NULL,
[FromService] [sysname] NOT NULL,
[ToService] [sysname] NOT NULL,
[OnContract] [sysname] NOT NULL,
[Handle] UNIQUEIDENTIFIER NOT NULL,
[CreateDate] DATETIME2 (7) NULL,
PRIMARY KEY CLUSTERED ([Identifier] ASC, [IdentifierType] ASC, [FromService] ASC, [ToService] ASC, [OnContract] ASC) ON [PRIMARY],
UNIQUE NONCLUSTERED ([Handle] ASC) ON [PRIMARY]
) ON [PRIMARY];
What appears to be happening is the DELETE is somehow deadlocking with the SEND but I am not sure how since I am using them in the same order in both the send procedure and the activated procedure. Also, RCSI is enabled on the database I am receiving the
deadlocks on.
EDIT:
I think I have found the culprit with lock acquisition order:
- In the usp_SendMessage proc:
The SELECT locks the conversation record
The SEND locks the conversation group
- In the timer activated proc on the initiator queue:
The RECEIVE locks the conversation group
The DELETE locks the conversation record
Given that I think there may be a few solutions:
There is some subtle difference between my code and the code from the article that I am not noticing that when fixed will resolve the deadlocking. I am hoping this is the case since it seems that others have used this pattern without issues as far as I
know.
Or...The deadlocking is inherent to the pattern the code is using and I can either:
Deal with the deadlocking by adjusting the deadlock priority on the activated stored procedure so that it becomes the victim, and I can implement retry logic.
Remove conversation timers and activation all together and resort to some sort of job that expires the conversation by polling it, where I can control the ordering.
My ultimate goal is to eliminate any deadlocking on usp_SendMessage so that it "never" fails.
I appreciate any feedback!
Thanks
I can understand why the deadlock happens. As you point out the activation procedure and the send SP acquire locks on the resources in reverse order.
Really why Remus does not consider this in his blog post, I don't know. But may I ask, since you have replaced @@spid as a key with two other columns, does this also mean that multiple processes can use the same conversation? I'm not so sure that
this is a good idea. I worked with an SB implementation which reuses conversations some months ago, and I recall that considered channing the pattern, but that I decided against it the end although I don't remember the exact details.
But so much is clear, if multiple processes can use the same handle, they will serialise on the SELECT with UPDLOCK. That will not happen if you change to REPEATABLEREAD, but I guess they will serialiase on the SEND instead.
The best way to address the problem appears to use SET LOCK_TIMEOUT 0 in the activation procedure and trap the the timeout error in a CATCH block, and let the message go back to the queue. This should be better than SET DEADLOCK_PRIORITY, since the there
will never be a deadlock that upholds the the sender.
Erland Sommarskog, SQL Server MVP, [email protected]
Similar Messages
-
Service Broker External Activator Service stuck in "Stopping" mode after error 90
Hi,
We are using the Service Broker External Activator Service and we've come across an error involving runtime checkpointing and the process not being able to access the EARecovery.rlog file.. it goes like this:
2014/06/09 10:15 VERBOSE
Checkpointing recovery log C:\Program Files\Service Broker\External Activator\log\EARecovery.rlog ...
2014/06/09 10:15 ERROR
The External Activator service is aborting ...
2014/06/09 10:15 EXCEPTION
ERROR = 90, Internal exceptions have occurred when External Activator is runtime checkpointing.
2014/06/09 10:15 EXCEPTIONDETAILS
Inner Exception:
2014/06/09 10:15 EXCEPTIONDETAILS
System.IO.IOException: The process cannot access the file 'C:\Program Files\Service Broker\External Activator\log\EARecovery.rlog' because it is being used by another process.
2014/06/09 10:15 EXCEPTIONDETAILS
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
2014/06/09 10:15 EXCEPTIONDETAILS
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
2014/06/09 10:15 EXCEPTIONDETAILS
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
2014/06/09 10:15 EXCEPTIONDETAILS
at ExternalActivator.LogManager.CompressRecoveryLog(LogRecoveryContext recoveryContext)
2014/06/09 10:15 EXCEPTIONDETAILS
at ExternalActivator.LogManager.Checkpoint(LogRecoveryContext recoveryContext)
2014/06/09 10:15 EXCEPTIONDETAILS
at ExternalActivator.LogManager.Log(LogRecord recoveryLogRec)
2014/06/09 10:15 EXCEPTIONDETAILS
at ExternalActivator.ApplicationMonitor.OnProcessExited(ProcessMonitor processMonitor)
2014/06/09 10:15 EXCEPTIONDETAILS
at ExternalActivator.ProcessMonitor.NotifySubscriber()
2014/06/09 10:15 EXCEPTIONDETAILS
at ExternalActivator.ProcessMonitor.OnProcessExited(Object a, EventArgs b)
2014/06/09 10:15 VERBOSE
Heartbeat-Thread is exiting...
2014/06/09 10:15 VERBOSE
Waiting for worker threads to finish...
2014/06/09 14:13 ======
================================================================================
2014/06/09 14:13 ======
================================================================================
This happened a few days ago and we are pretty sure nobody was using the file as this is a production application server... and then it happened again several days later...
We have to kill the process and restart the service to get things going again.
Any help would be greatly appreciated as this is not a viable way of doing things for us.
Thanks
Gabrieland we are pretty sure nobody was using the file as this is a production application server...
Hello Gabriel,
Is there maybe an anti-virus software running on the server, which accesses the file at the same time? If so, you may exclude the log file in the AV software.
Olaf Helper
[ Blog] [ Xing] [ MVP] -
Anyone can help with the below issue please? Much appreciated.
We have about 2k+ messages in sys.transmission_queue
Telnet to the ports 4022 is working fine.
Network connectivity has been ruled out.
The firewalls are OFF.
We also explicitly provided the permissions to the service account on Server A and Server B to the Service broker end points.
GRANT
CONNECT ON
ENDPOINT <broker> <domain\serviceaccount>
Currently for troubleshooting purposes, the DR node is also out of the Availability Group, which means that we right now have only one replica the server is now a traditional cluster.
Important thing to note is when a SQL Server service is restarted, all the messages in the sys.transmission queue is cleared immediately. After about 30-40 minutes, the errors are continued to be seen with the below
The
connection was
closed by the
remote end,
or an
error occurred while
receiving data:
'64(The specified network name is no longer available.)'We were able to narrow down the issue to an irrelevant IP coming into play during the data transfer. We tried ssbdiagnose runtime and found this error:
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Windows\system32>SSBDIAGNOSE -E RUNTIME -ID 54F03D35-1A94-48D2-8144-5A9D24B24520 Connect to -S <SourceServer> -d <SourceDB> Connect To -S <DestinationServer> -d <DestinationDB>
Microsoft SQL Server 11.0.2100.60
Service Broker Diagnostic Utility
An internal exception occurred: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
P 29830 Could not find the connection to the SQL Server that
corresponds to the routing address tcp://XX.XXX.XXX.199:4022. Ensure the tool is connected to this server to allow investigation of runtime events
The IP that corresponds to routing address is no where configured within the SSB. We are yet unsure why this IP is being referred despite not being configured anywhere. We identified that this IP belongs to one of nodes other SQL Server cluster, which has
no direct relation to the source server. We failed over that irrelevant SQL Server cluster and made another node active and to our surprise, the data from sys.transmission_queue started flowing. Even today we are able to reproduce the issue, if we bring
back this node [XX.XXX.XXX.199] as active. Since, its a high business activity period, we are not investigating further until we get an approved downtime to find the root cause of it.
When we get a approved downtime, we will bring the node [XX.XXX.XXX.199] as active and we will be running Network Monitor, Process Monitor and the SSB Diagnose all in parallel to capture the process/program that is accessing the irrelevant IP.
Once, we are able to nail down the root cause, I will share more information. -
SSIS Catalog views are not executing from PROC calling from a service broker
Hi Exprets,
I have a package deployed on SSISDB (the new concept in MS SQL 2012, SSIS catalogs). I have t-sql code in which i will be able to execute SSIS package in SSISDB with no problems. But if i place the same t-sql code inside of a procedure which will be called
by a service broker , the code is not executing.
I am using the following code to execute a package in the SSISDB catalog
Declare @execution_id bigint
EXEC [SSISDB].[catalog].[create_execution] @package_name=N'LoadToABC.dtsx',
@execution_id=@execution_id OUTPUT, @folder_name=N'ABC', @project_name=N'LoadToABC',
@use32bitruntime=False, @reference_id=Null
DECLARE @var0 NVARCHAR(200)
= N'D:\MyData\SampleText20120830100001.txt'
EXEC [SSISDB].[catalog].[set_execution_parameter_value] @execution_id, @object_type=30,
@parameter_name=N'strFileName', @parameter_value=@var0
EXEC [SSISDB].[catalog].[start_execution] @execution_id
This code executes if run it alone or placed in a regular stored procedure , but not executes if i palce this same code inside of a procedure which is being called/executed by a service broker call like this:
CREATE QUEUE dbo.SampleQueue
WITH STATUS=ON, ACTIVATION
(STATUS = ON, MAX_QUEUE_READERS
= 1,
PROCEDURE_NAME = spMessageProcSample,
EXECUTE AS OWNER);
The problem occurs if we call the SSIS catalogs inside a proc which will be calling through a service broker queue.
I am running all these steps on my local instance of SQL SERVER 2012 in which i am the administrator.
Please advice where i am doing wrong ?
Thanks,
Jyodhu.Hi ArthurZ,
Thanks for reply. What i ment was i tried with all the "EXECUTE AS" options. but no luck.
Can you please explain step by step if you can ? That would be great help.
This is the error message from server log.
Message
The activated proc '[dbo].[spMessageProcSample]' running on queue 'FileTableDB.dbo.SampleQueue' output the following: 'The server principal "USA\cccsat1nmg" is not able to access the database "SSISDB" under the current security context.'
I logged in with WIndows authentication (Admin) and i created all the objects including Integration services Catalog.
Thanks,
Jyodhu. -
Configuring Service Broker between SQL Server 2008 and 2012 on Intranet
Hello, I would need help in configuring Service broker. As both servers are on the intranet, I wanted to remain the most simple so I used no certificates and allowed anonymous access but still, using SSBDiagnose, I can see errors.
I would like to paste here my configuration and my usage of SSBDiagnose, I already asked a question about SSBDiagnose usage but this new question is rather on the usage of certificates and the configuration of SSB, for me to know if I am doing this in the
best possible way.
Reading on the web, I have read in few places that certificates are not mandatory and that Windows Authentication only can be used. Then, I read that even if endpoints don't request certificates, the communication between two servers will still requires
certificates so I am wondering where is the truth...
I have two servers:
EmployeesSvr (SQL Server 2012 Enterprise Edition with Always On, EmployeesSvr is the listener name in front of two virtual servers)
CREATE MESSAGE TYPE [//E/S/ETChanged] VALIDATION = WELL_FORMED_XML
CREATE CONTRACT [//E/S/ECContract] ([//E/S/ETChanged] SENT BY INITIATOR)
CREATE QUEUE [dbo].[ECQueue] WITH STATUS = ON , RETENTION = OFF , ACTIVATION ( STATUS = ON , PROCEDURE_NAME = [dbo].[SSB_ECQueueProc] , MAX_QUEUE_READERS = 1 , EXECUTE AS N'dbo' )
CREATE SERVICE [//E/S/ECService] ON QUEUE [dbo].[ECQueue] ([//E/S/ECContract])
CREATE ROUTE [RouteToSECService] WITH SERVICE_NAME = N'//S/S/ECService' , BROKER_INSTANCE = N'F...' , ADDRESS = N'TCP://SoftwaresSrv.test.com:4022'
CREATE REMOTE SERVICE BINDING [SECServiceBinding] TO SERVICE N'//S/S/ECService' WITH USER = [domain\SvcBrokerTestUser] , ANONYMOUS = ON
CREATE ENDPOINT [ESBEndpoint] STATE=STARTED AS TCP (LISTENER_PORT = 4022, LISTENER_IP = ALL) FOR SERVICE_BROKER (MESSAGE_FORWARDING = DISABLED, MESSAGE_FORWARD_SIZE = 10, AUTHENTICATION = WINDOWS NEGOTIATE, ENCRYPTION = DISABLED)
SoftwaresSvr (SQL Server 2008 R2)
CREATE MESSAGE TYPE [//E/S/ETChanged] VALIDATION = WELL_FORMED_XML
CREATE CONTRACT [//E/S/ECContract] ([//E/S/ETChanged] SENT BY INITIATOR)
CREATE QUEUE [dbo].[ECQueue] WITH STATUS = ON , RETENTION = OFF , ACTIVATION ( STATUS = ON , PROCEDURE_NAME = [dbo].[SSB_ECQueueProc] , MAX_QUEUE_READERS = 1 , EXECUTE AS N'dbo' )
CREATE SERVICE [//S/S/ECService] ON QUEUE [dbo].[ECQueue] ([//E/S/ECContract])
CREATE ROUTE [RouteToECService] WITH SERVICE_NAME = N'//E/S/ECService' , BROKER_INSTANCE = N'2...' , ADDRESS = N'TCP://EmployeesSvr.test.com:4022'
CREATE REMOTE SERVICE BINDING [EECServiceBinding] TO SERVICE N'//E/S/ECService' WITH USER = [domain\SvcBrokerTestUser] , ANONYMOUS = ON
CREATE ENDPOINT [SSBEndpoint] STATE=STARTED AS TCP (LISTENER_PORT = 4022, LISTENER_IP = ALL) FOR SERVICE_BROKER (MESSAGE_FORWARDING = DISABLED, MESSAGE_FORWARD_SIZE = 10, AUTHENTICATION = WINDOWS NEGOTIATE, ENCRYPTION = DISABLED)
My SSBDiagnose command :
ssbdiagnose -E CONFIGURATION
FROM SERVICE //E/S/ECService
-S EmployersSvr
-d EmployersDB
TO SERVICE //S/S/ECService
-S SoftwaresSvr
-d SoftwaresDB
ON CONTRACT //E/S/ECContract
The result :
Microsoft SQL Server 10.50.1600.1
Service Broker Diagnostic Utility
D 29978 EmployersSvr EmployersDB
No valid certificate was found for user domain\SvcBrokerTestUser
D 29977 SoftwaresSvr SoftwaresDB
The user domain\SvcBrokerTestUser from database EmployersDB on EmployersSvr cannot be mapped into this database using certificates
D 29933 SoftwaresSvr SoftwaresDB
The routing address TCP://EmployeesSvr.test.com:4022 for service //E/S/ECService does not match any of the IP addresses for EmployersSvr
An internal exception occurred: An exception occurred while executing a Transact-SQL statement or batch.
Thank you for any help, I am searching for several answers :
Can I use the setup as I defined, with no certificate ? Is it risky ?
Is there too many objects defined ? Is it mandatory to have a Route and a Remote Service Binding ? I don't understand how those two are working togheter...
Is it ok to use the same windows account on each side, do they only need an 'Open' access rigth or do they need to be db_owner ?
Best regards,
ClaudeHi Claude,
1.Can I use the setup as I defined, with no certificate ? Is it risky ?
Service broker does not have to use certificate. The Certificate is necessary when you want to use dialog security, by which you can encrypt all messages sent outside a SQL Server instance.
http://technet.microsoft.com/en-us/library/ms166036(v=SQL.105).aspx
2.Is there too many objects defined ? Is it mandatory to have a Route and a Remote Service Binding ?
Remote Service Binding is used to privde dialog security. If you donnot need the dialog security, the Remote Service Binding is not mandatory.
http://technet.microsoft.com/en-us/library/ms166042(v=SQL.105).aspx
By default, each database contains a route that specifies that messages for any service which does not have an explicit route are delivered within the SQL Server instance. Since you have communications between different instances, creating a route between
them is necessary.
http://technet.microsoft.com/en-us/library/ms166032(v=SQL.105).aspx
3.Is it ok to use the same windows account on each side, do they only need an 'Open' access rigth or do they need to be db_owner ?
The windows account must own the certificate used for authentication. You can find more information below.
http://technet.microsoft.com/en-us/library/ms166045(v=SQL.105).aspx
http://technet.microsoft.com/en-us/library/ms186278(v=sql.105).aspx
Best regards, -
SQL Server Service Broker Updating Stored procedure
how can you update the service broker stored procedure. when i update the stored procedure the changes dont come into affect. i have tried to alter the queue, waited for all jobs to finish, but some how still the old stored procedure is running. is there any
way i can force changes to the stored procedure.
i have tried sql profiler tracing but that didnt show any changes.
I cannot alter the service broker stored procedure, when I update the stored procedure it does not show any error and successfully gets updated but the changes does not come into affect.
Is it because I need to stop the queue of the service broker on both databases before the changes could come into affect?
Note: the service broker stored procedures produce and read xmls.Presumably, this is because the procedure is executing when you alter the procedure. And if the procedure never exits, the old code will keep on running. One way to address this is to have the procedure to return if a new message has not been picked up in,
say, 1000 milliseconds.
Here is a repro to shows what I'm talking about.
------------------------------- Service Broker Objects ------------------------------------------
CREATE MESSAGE TYPE OrderRequest VALIDATION = NONE
CREATE MESSAGE TYPE OrderResponse VALIDATION = NONE
go
CREATE CONTRACT OrderContract
(OrderRequest SENT BY INITIATOR,
OrderResponse SENT BY TARGET)
go
CREATE QUEUE OrderRequests WITH STATUS = OFF
CREATE QUEUE OrderResponses WITH STATUS = ON
go
CREATE SERVICE OrderRequests ON QUEUE OrderRequests (OrderContract)
CREATE SERVICE OrderResponses ON QUEUE OrderResponses (OrderContract)
go
-- Procedure to send a message and receive a response.
CREATE PROCEDURE send_and_get_answer AS
DECLARE @handle uniqueidentifier,
@binary varbinary(MAX)
SELECT @binary = CAST (N'Kilroy was here' AS varbinary(MAX))
BEGIN DIALOG CONVERSATION @handle
FROM SERVICE OrderResponses
TO SERVICE 'OrderRequests'
ON CONTRACT OrderContract
WITH ENCRYPTION = OFF
;SEND ON CONVERSATION @handle
MESSAGE TYPE OrderRequest (@binary)
WAITFOR (RECEIVE TOP (1)
@handle = conversation_handle,
@binary = message_body
FROM OrderResponses)
SELECT cast(@binary AS nvarchar(MAX)) AS response
END CONVERSATION @handle
go
-- Procedure to process a message
CREATE PROCEDURE ProcessOrders AS
SET NOCOUNT, XACT_ABORT ON
DECLARE @DialogHandle uniqueidentifier,
@MessageType sysname,
@binarydata varbinary(MAX)
-- Get next message of the queue.
WAITFOR (
RECEIVE TOP (1) @DialogHandle = conversation_handle,
@MessageType = message_type_name,
@binarydata = message_body
FROM OrderRequests
SELECT @binarydata = CAST( reverse( CAST( @binarydata AS nvarchar(MAX) )) AS varbinary(MAX))
; SEND ON CONVERSATION @DialogHandle
MESSAGE TYPE OrderResponse (@binarydata)
END CONVERSATION @DialogHandle
go
-- Make this an activaton procedure.
ALTER QUEUE OrderRequests WITH
STATUS = ON,
ACTIVATION (STATUS = ON,
PROCEDURE_NAME = ProcessOrders,
MAX_QUEUE_READERS = 1,
EXECUTE AS OWNER)
go
-------------------------------- Send a message -------------------------------------------
EXEC send_and_get_answer
go
------------------------ Change the procedure --------------------------------
ALTER PROCEDURE ProcessOrders AS
SET NOCOUNT, XACT_ABORT ON
DECLARE @DialogHandle uniqueidentifier,
@MessageType sysname,
@binarydata varbinary(MAX)
-- Get next message of the queue.
WAITFOR (
RECEIVE TOP (1) @DialogHandle = conversation_handle,
@MessageType = message_type_name,
@binarydata = message_body
FROM OrderRequests
SELECT @binarydata = CAST( upper( CAST( @binarydata AS nvarchar(MAX) )) AS varbinary(MAX))
; SEND ON CONVERSATION @DialogHandle
MESSAGE TYPE OrderResponse (@binarydata)
END CONVERSATION @DialogHandle
go
-------------------------------- Send new message -------------------------------------------
EXEC send_and_get_answer -- Still produces a message in reverse.
EXEC send_and_get_answer -- Now we get the expected result.
go
DROP SERVICE OrderRequests
DROP SERVICE OrderResponses
DROP QUEUE OrderRequests
DROP QUEUE OrderResponses
DROP PROCEDURE ProcessOrders
DROP PROCEDURE send_and_get_answer
DROP CONTRACT OrderContract
DROP MESSAGE TYPE OrderRequest
DROP MESSAGE TYPE OrderResponse
go
Erland Sommarskog, SQL Server MVP, [email protected] -
How to use Service Broker, where and when we gonna use it.
Hi all,
I have task to implement SQL service broker for some insert statement, am bit confused where i start and how to implement like it may in Database or Server side(ASP.Net- c#), some where.
What the main advantage of using SQL Service broker?
Thanks,
Jai.There is more than one place where Service Broker fits in. Generally, one can say that Service Broker permits you to implement things asynchronously. For instance, when a row is updated in a table a mail should be sent to someone. Rather than having a trigger
that sends the mail on the spot, the trigger could post a message on a Service Broker queue. Then there could be an activation procedure which reacts to this message and composes and sends the mail. This activation can be in the same database - but it can
also be on a completely different server which does not even have a direct connection to the actual server.
Activation can also be external. That is, there is an application that polls the queue, and again this could be on an other server, and when there is a message in the queue the application processes it.
Roger Wolter's book is an excellent introduction to Service Broker:
http://www.amazon.com/Rational-Server-Service-Broker-Guides/dp/1932577270/ref=sr_1_1?ie=UTF8&qid=1420025225&sr=8-1&keywords=Roger+Wolter+service+broker
Also, don't overlook Remus Rusanu's blog, which is an excellent resource for development patterns with Service Broker:
http://rusanu.com/?s=service+broker
Both Roger and Remus worked on the development of Service Broker, so they know what they are talking about.
Erland Sommarskog, SQL Server MVP, [email protected] -
Service Broker Disabled but it comes back showing its Enabled.
Used to disable SERVICE BROKER in single user mode :
ALTER DATABASE [Database_name] SET DISABLE_BROKER;
SELECT is_broker_enabled FROM sys.databases WHERE name = 'Database_name';
when i checked the database after disabling, it shows 'is_broker_enabled'=1
wht can be problem.
Naveen| Press Yes if the post is useful.Interestingly the broker is disabled but i see the receive_wait messages on 'Activity monitor' for the database where service broker is disabled.
Any thoughts
Naveen| Press Yes if the post is useful. -
Send Email using service broker
Hi,
i have a service broker application that i send message to the queue and a specific SP reads the message and process it, part of this processing is sending the information found on that message to a specific email accounts. this means i have two service broker applicatins, one for my business (sending messages to queue to be processed and the secound one is the SendEmail service)
when i send email using the SP "msdb.dbo.sp_send_dbmail" the email is recieved 100% true, but when i come to send the email through the SP which recieve the messages from the SB queue, the email is not sent and i dont know where it goes.
this means that i cant read from a queue and send to another one at the same time... can you help me in this!
-RanaActivated procedures execute under an EXECUTE AS context that prevents calls into anoter database (like msdb). See
http://rusanu.com/2006/03/07/call-a-procedure-in-another-database-from-an-activated-procedure/ for details.
This Solved my issue.
My Error
The activated proc '[dbo].[usp_SB_Rcv_ApplicationError]' running on queue 'ServerDeadLockNotification.dbo.ApplicationError_Rcv_Q' output the following: 'The EXECUTE permission was denied on the object 'sp_send_dbmail', database 'msdb', schema 'dbo'.'
Code Causing the Error:
CREATE PROCEDURE dbo.usp_SB_Rcv_ApplicationErrorr
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Handle UNIQUEIDENTIFIER;
DECLARE @MessageType SYSNAME;
DECLARE @Message XML
DECLARE @BodyTable NVARCHAR(MAX);
RECEIVE TOP (1) @Handle = conversation_handle,
@MessageType = message_type_name,
@Message = message_body
FROM [ApplicationError_Rcv_Q];
IF(@Handle IS NOT NULL AND @Message IS NOT NULL)
BEGIN
-- parse the message xml to get the error details
-- build the HTML table for send_dbmail
SET @BodyTable = (SELECT dbo.GetErrorEmailBody(@Message));
-- send the mail on the default profile
EXEC msdb.dbo.sp_send_dbmail
@recipients='[email protected]',
@subject = 'Errors',
@body = @BodyTable,
@body_format = 'HTML' ;
END CONVERSATION @Handle;
END
END
The Fix:
ALTER DATABASE [ServerDeadLockNotification]
SET TRUSTWORTHY
ON -
Service Master / Activity Master description change Issue
Dear Experts,
I am facing problem with Service master / Activity Master description change problem.
Steps in the problem -
1) Service Master / Activity Master created.
2) Long term purchase order (with large quantity) is created.
3) Service entry sheet and Invoice has been posted for the Purchase Order.
Due Service master / Activity master description change requirement from client, description of the
Services are changed.
But it is not updated in Purchase order. (As purchase order has been created before service master description change)
and when i am trying to post next service entry sheet with reference to the long term purchase order created,
it is not adopting the new one service description.
Thanks in AdvanceHi Kiran
The solution to your issue could be achieved as follows:
In the item level 'Service' tab for the corresponding PO line item, change the quantity to which you have already made Service Entry sheet. Then create a new line item with the Service number, once you enter the Service number you would see the new description here. Then when you create a Service Entry sheet with reference to PO, the system would ask you to select one of the two entries you have in PO. Here select the new entry which you have made.
Thanks
Prashanth -
Alert: SQL Server Service Broker or Database Mirroring Transport stopped
Hi Team,
I got this error message even no one DB configured as mirroring ???
Alert: SQL Server Service Broker or Database Mirroring Transport stopped Priority: 0 Severity: 2 Resolution state: New
Alert description: The Database Mirroring protocol transport has stopped listening for connections.Can you check the rule. By default the configurations are disabled state that is the reason you are getting the alert.
If it's not configured properly then you might need to override it
--Prashanth -
Contact Service Queue Activity Report (by CSQ) Report SQL example
I've been tasked to recreate the Contact Service Queue Activity Report (by CSQ) Report, with SQL in SQL Server 2008 RS, Can someone give me an example or actual sql for this report? I've tried to folllow the hints about joining in the documentation, however, my reported numbers are much higher than what the Cisco report is giving back.
Thanks to anybody who knows where this sql is.
LyleHi Lyle,
Please refer the section "Restrictions with Generating Historical Reports" in the below UCCX release notes.
http://www.cisco.com/web/ccbu/CRS/8/0/2/SU3/UCCX_802_SU3_Relnote.pdf
CSCtj96987 : Reports unable to generate large set of records bcz of tmp dbspace limit
Defect Description:
Customers are unable to generate HR reports for a larger duration because of a limitation set based on first 10k records in CCD table. Many customers require to generate reports for a complete month which they are unable to do now in 8.x
affected reports are :
Abandoned Call Detail
Aborted Rejected Call Detail
Agent Detail
Agent Login Logout
Agent State Detail
Detailed Call by Call CCDR
Detailed Call CSQ Agent
Additional Info
1. Customer may get runtime error if the temp dbspace gets full. HRC log will state clearly that the system ran out of disk space. This will happen if the customer is running reports for a very large set of data or running large number of simultaneous HR sessions involving considerable amount of data.
2. The temp dbspace is fixed at 2GB and cannot grow automatically when required. So, if the space is filled completely, HR reports will error out. The temp dbspace will be freed when the session ends. So, If you get run time error anytime, please restart HRC and try to generate report for a smaller period of time.
3. It is recommended to generate reports approximately upto 200,000 rows when a single session is running to avoid getting run time errors. If multiple sessions are running, modify the figure accordingly.
4. If the customer is running a single node setup, it is highly recommended to generate reports in the off-peak hours.
Fixed in :
8.0(2)SU2, 8.5(1)SU2, 9.0(1)
You can think of upgrading your UCCX system to the above releases for this issue fix.
Thanks,
Anand -
URGENT: Service Call Activity Issue
Hi guys, I have a seriously irritating issue concerning the linking of an activity to service call.
As of Service Pack 01, Patch 36 (at least as far as I know) I get the following error when attempting to create and link an activity to a service call:
Error Code: -5002
Error Description: A service call activity does not exist
I use the folliwing code;
If oServ.GetByKey(MRI) Then
If DocType = "QT" Then
oAct = oComp.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oContacts)
oAct.Activity = SAPbobsCOM.BoActivities.cn_Task
oAct.CardCode = oServ.CustomerCode
oAct.DocEntry = DocID
oAct.DocType = 23
oDoc = oComp.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oQuotations)
If oDoc.GetByKey(DocID) Then
oAct.Notes = "Sales Quote: " & oDoc.Comments
End If
oAct.Details = "Sales Quote " & DocID & " auto created by MRI " & MRI & ""
If oAct.Add <> 0 Then
oApp.SetStatusBarMessage("Error adding Linked Document Activity for Sales Quote " & DocID & " : " & oComp.GetLastErrorDescription)
oLog.WriteLog("Error adding Linked Document Activity for Sales Quote " & DocID & " : " & oComp.GetLastErrorCode & oComp.GetLastErrorDescription, EventLogEntryType.Error)
Else
oServ.Activities.Add()
oServ.Activities.ActivityCode = oComp.GetNewObjectKey
oServ.Activities.SetCurrentLine(oServ.Activities.Count() - 1)
End If
If oServ.Update <> 0 Then
oApp.SetStatusBarMessage("Error linking Expense Document " & DocID & ":" & oComp.GetLastErrorDescription)
oLog.WriteLog("Error linking Expense Document " & DocID & ":" & oComp.GetLastErrorCode & "-" & oComp.GetLastErrorDescription, EventLogEntryType.Error)
End If
the Activity is added without any problem, but the error comes when linking it to the Service Call (oServ.Update)
Can you please help, I'm going insane with this problem.this is how i got it to work:
ServiceCalls sc = null;
sc = (ServiceCalls)company.GetBusinessObject(BoObjectTypes.oServiceCalls);
if (!sc.GetByKey(callId))
throw new Exception("Failed to add service call activity! Service call does not exist!");
if (sc.Activities.Count == 1)
sc.Activities.SetCurrentLine(sc.Activities.Count - 1);
string temp = sc.Activities.ActivityCode.ToString();
if (!string.IsNullOrEmpty(temp) && !temp.Equals("0"))
sc.Activities.Add();
else
sc.Activities.Add();
sc.Activities.SetCurrentLine(sc.Activities.Count - 1);
sc.Activities.ActivityCode = int.Parse(lastAcctivity);
if (sc.Update() != 0)
company.GetLastError(out errorCode, out errorMsg);
if (null != sc)
System.Runtime.InteropServices.Marshal.ReleaseComObject(sc);
sc = null;
throw new Exception(errorCode + " -> " + errorMsg);
You could either use that piece of code or make an insert in SCL5. -
Can service broker work between SQL Server 2008 and 2012, ssbdiagnose returned an error !
Hello,
We have a setup of three applications that sends and receive messages using Service Broker.
One part is on a server, we'll call 'S' have Microsoft SQL Server 2008 (SP3) - 10.0.5512.0 (X64)
The other part, we'll call 'E' use to have Microsoft SQL Server 2008 (SP3) - 10.0.5512.0 (X64).
But I am migrating these apps to a new server, we'll call 'C' that has: Microsoft SQL Server 2012 (SP1) - 11.0.3339.0 (X64)
I have used this command line tool to test it :
ssbdiagnose -E CONFIGURATION FROM SERVICE "//E/S/CService" -S "ServerC" -d EDatabase TO SERVICE "//S/S/ECService" -S ServerS -d SDatabase ON CONTRACT //E/S/ECContact
It returned:
An internal exception occurred: Cannot read property ServiceBrokerGuid.
This property is not available on SQL Server 7.0.
So, I am wondering, is it supposed to work between these two versions ?
As more info, in the previous setup, it was using certificates but I have changed the Endpoints to use only Windows Authentication.
Thanks for any advice.
ClaudeHello,
Many thanks to you and Fanny for looking at my question.
In fact I was unclear, please let me provide you with more details.
Maybe the use of "always on" plays a role here... I will use different names so it might be clearer...
ServerSoftware2008 server has SoftwareDB database.
ServerEmployees2008 server has EmployeesDB database.
Service broker use to work fine between those two above, with certificates.
The new server comes in, two virtual servers with SQL Server 2012 Enterprise Edition with Always On.
I call it ServerEmployeesC but this is the listener. Behind, there is ServerEmployees2012_A and ServerEmployees2012_B and of course, both have a EmployeesDB database.
So, to use SSBDiagnose, I wonder if I need to use quotes around values and if I can use the listener name with FQDN. Concerning the use of instance name in the syntax, there is only one instance per server, is it best practice to use it on the command
line ?
Here is again, my command :
ssbdiagnose -E CONFIGURATION FROM SERVICE "//E/S/E" -S "ServerEmployeesC.sub.acme.com" -d EmployeesDB TO SERVICE "//S/S/E" -S "ServerSoftware2008.sub.acme.com" -d SoftwareDB ON CONTRACT //E/S/E
Again, many thanks for any help you will be able to provide, the people who configured this application at first are no longer here and I am trying to configure the new server in a task of migrating to SQL Server 2012 for one of the two servers involved
and I am having a lot of problems doing it.
Best regards,
Claude -
Hi All,
I have requirement to implement SQL server service broker in SQL server 2008, please guide me for that, how and why we use for that, then have any other option to achieve.
Please give any good stuff to learn service broker.
Thanks,
Jai.This is a very good book to learn about Service Broker:
http://www.amazon.com/Rational-Server-Service-Broker-Guides/dp/1932577270/ref=sr_1_1?ie=UTF8&qid=1418942042&sr=8-1&keywords=%22roger+wolter%22+%22service+broker%22&pebp=1418942044114
In difference from many other computer books, this is not a brick, but only 220 pages.
Also, Remus Rusanu's blog covers many important concepts with Service Broker:
http://rusanu.com/?s=service+broker
Erland Sommarskog, SQL Server MVP, [email protected]
Maybe you are looking for
-
How to extract data from BCS consolidation cube to Group BW extraction cube
Gurus, I have to figure out a way to extract data from a local BCS consolidation totals cube to a group BW extraction cube via a virtual cube in between the too...How can i do the extraction and what are the different ways in which it can be done.. D
-
Hi: I use InDesign CS4 in my job as a church office manager. I print bulletins that are usually 3 letter-sized pages, landscape, 2-sided, and newsletters that are 2 11x17 pages, landscape, 2-sided. I'm working in Mac OS 10.5.8. Until today, I was usi
-
Plus sign in front of phone number
I notice when I plug my iphone into itunes, I have the phone number "+1 (123) 456-7890" what does the plus sign mean? I notice several contacts also had it after updating to iOS 501
-
InDesign CS5 Crashes on PDF Export if Suitcase Fusion 3 Auto Activation is on
I just started having a problem after upgrading from SF2 to 3 and using InDesign CS5. My exports to PDF were all crashing as soon as the PDF creation background process started. I tried all kinds of tests and troubleshooting to figure out what was
-
Can't open folders, please help :(
Well it appeared couple of weeks ago, I thought it's my USB problem, but after I tried to open folder on Mac I had the same problem. So basically this is what happens: When I open any folder, lets say "folder one" and it contains some files and folde