Showing posts with label service. Show all posts
Showing posts with label service. Show all posts

Monday, March 26, 2012

Removal from sys.transmission_queues on exceeding LIFETIME

Hello,

We needed to detach a database that contained a target ServiceBroker service and wanted to do this without impacting the rest of our system. The idea was the ServiceBroker would enqueue message to this service to be pickedup when the database was re-attached. Our sequence to do this was:

1. Disable the queue on the target service forcing ServiceBroker to queue in the initating side transmission queue.

2. Detach the database.

3. Re-attach the database.

4. Re-enable the queue

Messages sent to the service have a specified LIFETIME. What appeared to happen was that messages were being stored in the transmission queue as expected but on hiting the LIFETIME period they were being removed from the transmission queue and were therfore "lost".

Has anyone else experienced this or can anyone suggest what we are doing wrong.

Incidentally, beaware that detaching a database will disable ServiceBroker in that database when it is re-attached - we discovered that one the hard way :-)

Any suggestions gratefully recieved.

We have now removed the LIFETIME property from our dialogs in order to reduce the risk of this happening and it all seems fine. My only concern now is that the LIFETIME EXCEEDED message is a Broker error, so does this mean that the same will hold true for all Broker errors that are generated whilst a message is in the transmission queue?|||

Prior to SP2 when receiving an Error or EndDialog message the sys.transmission_queue was drained for the that dialog. The idea was that applications that needed to look at the messages sent in case of error whould use queue RETENTION = ON. With SP2 we introduced a change in which the messages stay in sys.transmission_queue but ar enot being attempted to delivery and they are deleted only after the applications issues the END CONVERSATION.

So yes, any error message will cause the behavior your observed. Either use retention to save the messages sent or upgrade to SP2.

|||

Ian Mitchen wrote:

Incidentally, beaware that detaching a database will disable ServiceBroker in that database when it is re-attached - we discovered that one the hard way :-)

Also restore of a backup will disable the broker. SSB is intedend primarily for distributed applications and one has to consider the problems that can happen when only one side of the conversation is moved (i.e. database is detached/attached): routes have to be fixed, endpoint security has to be set up again for the new host etc. When a backup is restored, the situation is more dramatical, as the peer might be in a more advanced stage of a conversation (i.e. restorer db has next sequence number on a conversation N, but peer is already expecting N+2). In this case the only solution is to error the conversation.

For these considerations the restore and attach operations disable the service broker in the database. One has to inspect the database, ensure is in a consistent state with it's peers and then enable it.

|||

Thanks for a great response, that's filled another gap in my knowledge.

Cheers,

Ian

Friday, March 23, 2012

Removal from sys.transmission_queues on exceeding LIFETIME

Hello,

We needed to detach a database that contained a target ServiceBroker service and wanted to do this without impacting the rest of our system. The idea was the ServiceBroker would enqueue message to this service to be pickedup when the database was re-attached. Our sequence to do this was:

1. Disable the queue on the target service forcing ServiceBroker to queue in the initating side transmission queue.

2. Detach the database.

3. Re-attach the database.

4. Re-enable the queue

Messages sent to the service have a specified LIFETIME. What appeared to happen was that messages were being stored in the transmission queue as expected but on hiting the LIFETIME period they were being removed from the transmission queue and were therfore "lost".

Has anyone else experienced this or can anyone suggest what we are doing wrong.

Incidentally, beaware that detaching a database will disable ServiceBroker in that database when it is re-attached - we discovered that one the hard way :-)

Any suggestions gratefully recieved.

We have now removed the LIFETIME property from our dialogs in order to reduce the risk of this happening and it all seems fine. My only concern now is that the LIFETIME EXCEEDED message is a Broker error, so does this mean that the same will hold true for all Broker errors that are generated whilst a message is in the transmission queue?|||

Prior to SP2 when receiving an Error or EndDialog message the sys.transmission_queue was drained for the that dialog. The idea was that applications that needed to look at the messages sent in case of error whould use queue RETENTION = ON. With SP2 we introduced a change in which the messages stay in sys.transmission_queue but ar enot being attempted to delivery and they are deleted only after the applications issues the END CONVERSATION.

So yes, any error message will cause the behavior your observed. Either use retention to save the messages sent or upgrade to SP2.

|||

Ian Mitchen wrote:

Incidentally, beaware that detaching a database will disable ServiceBroker in that database when it is re-attached - we discovered that one the hard way :-)

Also restore of a backup will disable the broker. SSB is intedend primarily for distributed applications and one has to consider the problems that can happen when only one side of the conversation is moved (i.e. database is detached/attached): routes have to be fixed, endpoint security has to be set up again for the new host etc. When a backup is restored, the situation is more dramatical, as the peer might be in a more advanced stage of a conversation (i.e. restorer db has next sequence number on a conversation N, but peer is already expecting N+2). In this case the only solution is to error the conversation.

For these considerations the restore and attach operations disable the service broker in the database. One has to inspect the database, ensure is in a consistent state with it's peers and then enable it.

|||

Thanks for a great response, that's filled another gap in my knowledge.

Cheers,

Ian

sql

Remoting timeout when calling SSIS package execute from a windows service

When running an integration services package from a windows service I get the "Object ... has been disconnected or does not exist at the server." exception after aproximately six minutes of execution.

This is *not* my windows service failing. I can loop indefinately while tracing to a log file within the service and it will run forever. While calling the mypackage.execute(...) method however, after six minutes (give or take) the exception is thrown...

my code looks something like this:
<code>
dim foo as Microsoft.SqlServer.Dts.Runtime.Application
mypackage = foo..LoadPackage(strimportPkgFilename, pkgevents)
results = myPackage.Execute(Nothing, Nothing, pkgevents, Nothing, Nothing)
</code>

<error>
A first chance exception of type 'System.Runtime.Remoting.RemotingException' occurred in mscorlib.dll
Exception in: frmMyForm.DoImports
Message: Object '/b76f98a0_5bd9_49d8_a524_eeb49d55b303/bqbhkjnaofq_ifr_cwz+srid_1.rem' has been disconnected or does not exist at the server.
</error>

oddly, this same code works perfectly if I run it within a windows form application no matter how long it takes.

It also runs fine if the package can complete in under six minutes.

Any suggestions?

Mark

To give a little update, I'm still having this problem despite exhausting works around I've come up with.

* I've threaded the call to package.Execute, checking its status in a while loop every 60 seconds until it finishes. Still encounter the exception. This behaves as though it should work. The status and execution appear to work asynchronously.

* I've threaded the call to my service, calling my own status function which tests the status of shared MyPackage, every 60 seconds. Still encounter the remoting exception after ~6 minutes.

Every piece is busy making requests through the whole chain of accessible interactions frequently enough to maintain all known remoting timeout constraints and the problem persists.

It confuses me why the same code works in a windows form, but does not work in a windows service. The exception is defiantly being thrown from within package.Execute. I can loop indefinitely within the service without calling package Execute. I can also catch and disregard the exception and still provide status to the client within the service.

Looking for suggestions...

|||

SSIS does not use remoting. The exception is caused by remoting however, so you need to find out who introduced remoting? My ideas

1) you use remoting as link between client and server - then the exception is between the client and the service, which does not fit with the statement that it is thrown from within package.Execute and you can catch this exception (but did you try?)

2) you create multiple application domains in the service - if you do this, make sure you only use SSIS from default application domain. If you run the package from non-default application domain, some SSIS objects can be created in that app domain, but some in default app domain (a lot of SSIS is native code, and it is not aware of app-domains), which may cause failures like this one.

Remoting timeout when calling SSIS package execute from a windows service

When running an integration services package from a windows service I get the "Object ... has been disconnected or does not exist at the server." exception after aproximately six minutes of execution.

This is *not* my windows service failing. I can loop indefinately while tracing to a log file within the service and it will run forever. While calling the mypackage.execute(...) method however, after six minutes (give or take) the exception is thrown...

my code looks something like this:
<code>
dim foo as Microsoft.SqlServer.Dts.Runtime.Application
mypackage = foo..LoadPackage(strimportPkgFilename, pkgevents)
results = myPackage.Execute(Nothing, Nothing, pkgevents, Nothing, Nothing)
</code>

<error>
A first chance exception of type 'System.Runtime.Remoting.RemotingException' occurred in mscorlib.dll
Exception in: frmMyForm.DoImports
Message: Object '/b76f98a0_5bd9_49d8_a524_eeb49d55b303/bqbhkjnaofq_ifr_cwz+srid_1.rem' has been disconnected or does not exist at the server.
</error>

oddly, this same code works perfectly if I run it within a windows form application no matter how long it takes.

It also runs fine if the package can complete in under six minutes.

Any suggestions?

Mark

To give a little update, I'm still having this problem despite exhausting works around I've come up with.

* I've threaded the call to package.Execute, checking its status in a while loop every 60 seconds until it finishes. Still encounter the exception. This behaves as though it should work. The status and execution appear to work asynchronously.

* I've threaded the call to my service, calling my own status function which tests the status of shared MyPackage, every 60 seconds. Still encounter the remoting exception after ~6 minutes.

Every piece is busy making requests through the whole chain of accessible interactions frequently enough to maintain all known remoting timeout constraints and the problem persists.

It confuses me why the same code works in a windows form, but does not work in a windows service. The exception is defiantly being thrown from within package.Execute. I can loop indefinitely within the service without calling package Execute. I can also catch and disregard the exception and still provide status to the client within the service.

Looking for suggestions...

|||

SSIS does not use remoting. The exception is caused by remoting however, so you need to find out who introduced remoting? My ideas

1) you use remoting as link between client and server - then the exception is between the client and the service, which does not fit with the statement that it is thrown from within package.Execute and you can catch this exception (but did you try?)

2) you create multiple application domains in the service - if you do this, make sure you only use SSIS from default application domain. If you run the package from non-default application domain, some SSIS objects can be created in that app domain, but some in default app domain (a lot of SSIS is native code, and it is not aware of app-domains), which may cause failures like this one.

remotely start/stop sql server service in a workgroup

hi, i have an administrator account on a box, there is a sql server pc
in the same workgroup w/ a different admin pass (which i know ^_^, and
the sql sa pass too), how can i restart the sql server service from my box ?You can use xp_cmdshell with NET START/STOP MSSQLSERVER command. On you
command prompt type in NET START /? for details on this DOS command. For
details on xp_cmdshell, refer to SQL Server Books Online.
Anith|||Anith Sen wrote:
> You can use xp_cmdshell with NET START/STOP MSSQLSERVER command. On you
> command prompt type in NET START /? for details on this DOS command. For
> details on xp_cmdshell, refer to SQL Server Books Online.
>
xp_cmdshell is deleted(as recomended by every sql server security
quide), i can kill the process using pskill, but could that lead to data
loss?|||You can stop using the TSQL SHUTDOWN command.
At the OS level, you can both start and stop using NETSVC.EXE (Google for it
).
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/
Blog: http://solidqualitylearning.com/blogs/tibor/
"Fred" <fred@.ilovespam.com> wrote in message news:exFBLGgHGHA.2036@.TK2MSFTNGP14.phx.gbl...[
color=darkred]
> hi, i have an administrator account on a box, there is a sql server pc
> in the same workgroup w/ a different admin pass (which i know ^_^, and
> the sql sa pass too), how can i restart the sql server service from my box ?[/colo
r]

Tuesday, March 20, 2012

Remote Server into a named Instance of SQL Server 2005

We are setting up a database server with 2 instances of SQL Server 2005. One for the default and another for Reporting Service. I have them installed but when I try to a registration from another Server for the Reporting Service Instance I can not get in. I am using the sa userid and password, the same one that works when I am on the server but I get an error that says Remote Server connections may not be allowed. When I go to properties the Allow remote connections box is checked. Anyone know what else I need to do to get to the named instance?If you have another instance on the server it probably uses not the default port. If you have chosen another port than the default 1433 for the named instance, you should either start SQL Browser (which will handle request and will forward to the appropiate port on the server) or you directly name it within your connecting application by using the following syntax:

Servername\InstanceName,portnumber.

HTH, Jens Suessmeyer.

http://www.sqlserver2005.de

Monday, March 12, 2012

Remote Procedure Call Failed

Hi,
We are running IIS 4 under NT Server 4.0 Server, Serice pack 3; SQL
Server 6.5, Service Pack 3 and ASP 2.0, for our development databases.
We recently upgraded to IIS 4 and since then we keep getting thid
Remote Procedure error.
The exact error reads:
The server has reached the maximum recovery limit for the application
during the processing of your request. Please contact the server
administrator for assistance.
The next message that comes up is:
Server Application Error
The server has reached the maximum recovery limit for the application
during the processing of your request. Please contact the server
administrator for assistance.HTTP/1.1 500 Server Error Server:
Microsoft-IIS/4.0 Date: Mon, 29 Mar 1999 22:09:57 GMT Connection:
close Content-Type: text/html Content-Length: 93 The remote procedure
call failed.
We keep rebooting the server but this error persists. I can't find
anything that points to what can be causing this.
Has anyone else come across this problem?
Thanx in advance,
-=lata=-Lata,
1. Does this error happen only on the IIS? At the time of error, are you
able to use Query analyser and enterpirse manager and other client
connections to connect to sql server?
2. When you say you rebooted the server, is it the IIS server or the sQL
Server or the Windows server?
If other sql server applications and client connections are running fine,
then it could be an IIS issue.
Thanks,
Vikram Jayaram
Microsoft, SQL Server
This posting is provided "AS IS" with no warranties, and confers no rights.
Subscribe to MSDN & use http://msdn.microsoft.com/newsgroups.

Remote Procedure Call Failed

Hi,
We are running IIS 4 under NT Server 4.0 Server, Serice pack 3; SQL
Server 6.5, Service Pack 3 and ASP 2.0, for our development databases.
We recently upgraded to IIS 4 and since then we keep getting thid
Remote Procedure error.
The exact error reads:
The server has reached the maximum recovery limit for the application
during the processing of your request. Please contact the server
administrator for assistance.
The next message that comes up is:
Server Application Error
The server has reached the maximum recovery limit for the application
during the processing of your request. Please contact the server
administrator for assistance.HTTP/1.1 500 Server Error Server:
Microsoft-IIS/4.0 Date: Mon, 29 Mar 1999 22:09:57 GMT Connection:
close Content-Type: text/html Content-Length: 93 The remote procedure
call failed.
We keep rebooting the server but this error persists. I can't find
anything that points to what can be causing this.
Has anyone else come across this problem?
Thanx in advance,
-=lata=-
Lata,
1. Does this error happen only on the IIS? At the time of error, are you
able to use Query analyser and enterpirse manager and other client
connections to connect to sql server?
2. When you say you rebooted the server, is it the IIS server or the sQL
Server or the Windows server?
If other sql server applications and client connections are running fine,
then it could be an IIS issue.
Thanks,
Vikram Jayaram
Microsoft, SQL Server
This posting is provided "AS IS" with no warranties, and confers no rights.
Subscribe to MSDN & use http://msdn.microsoft.com/newsgroups.

Remote ODBC Connection problem \

Hi

I think i have a very unique issue ...

Running 2 machines
Win2000 / WinXP
Both have Sql / Service packs
Identical ODBC Setup

The issue is as follows :
Both machines CAN access The internet server through ODBC ! (so i dont
think the problem lies here)
I CAN connect to a server on the internet through a local web page on
W2k Box; BUT NOT on the WINXP machine ?
I think there is a IIS Prob maybe .. Checked iUser Security settings on
both and are identical

Any 1 have a suggestion ?

Thanks in advancelighthammer (lighthammer@.webmail.co.za) writes:
> I think i have a very unique issue ...
> Running 2 machines
> Win2000 / WinXP
> Both have Sql / Service packs
> Identical ODBC Setup
> The issue is as follows :
> Both machines CAN access The internet server through ODBC ! (so i dont
> think the problem lies here)
> I CAN connect to a server on the internet through a local web page on
> W2k Box; BUT NOT on the WINXP machine ?
> I think there is a IIS Prob maybe .. Checked iUser Security settings
> on both and are identical

I'm having a hard time to understand what you are connecting to. Is
"the internet server" and "a server on the Internet" the same machine?
Where does IIS comes into the picture? (Warning: I know next to nothing
about IIS.)

What error messages do you get?

Could the Windows firewall have anything to do with it?

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp

Friday, March 9, 2012

Remote messages not working – message vanishes

I need some assistance with getting service broker to work across servers. I have 2 separate servers and I am trying to send a message from one server to the other. No error is generated when sending the message and I get no records in the transmission queue of the sending server, however the message does not arrive on the receiving server. Where is the message going?

Here is the code I use to create the service broker objects that are being used…

RUN THIS ON THE SENDING SERVER:

CREATE MESSAGE TYPE [MyMessage] VALIDATION = NONE

CREATE MESSAGE TYPE [MyResponse] VALIDATION = NONE

GO

CREATE CONTRACT [MyContract] (

MyMessage SENT BY INITIATOR,

MyResponse SENT BY TARGET)

GO

CREATE QUEUE [MyInitiatorQueue] with status = ON

CREATE QUEUE [MyTargetQueue] with status = ON

GO

CREATE SERVICE [MyInitiatorService] ON QUEUE [MyInitiatorQueue]

GO

CREATE ROUTE [RouteToODS]

WITH

SERVICE_NAME = N'MyTargetService',

BROKER_INSTANCE = '1BB213E2-67A7-4059-BAF8-D9B5F31E358E',

ADDRESS = N'TCP://CONSULT01:4022'

GO

CREATE ENDPOINT DWHEndPoint

STATE = STARTED

AS TCP (LISTENER_PORT = 4022)

FOR SERVICE_BROKER (

AUTHENTICATION = WINDOWS,

ENCRYPTION = DISABLED)

GO

RUN THIS ON THE RECEIVING SERVER:

CREATE MESSAGE TYPE [MyMessage] VALIDATION = NONE

CREATE MESSAGE TYPE [MyResponse] VALIDATION = NONE

GO

CREATE CONTRACT [MyContract] (

MyMessage SENT BY INITIATOR,

MyResponse SENT BY TARGET)

GO

CREATE QUEUE [MyInitiatorQueue] with status = ON

CREATE QUEUE [MyTargetQueue] with status = ON

GO

CREATE SERVICE [MyTargetService] ON QUEUE [MyTargetQueue] ([MyContract])

GO

CREATE ROUTE [RouteToDWH]

WITH

SERVICE_NAME = N'MyInitiatorService',

BROKER_INSTANCE = 'F0BF4E80-704E-4CFE-80FC-637A1EC128C5',

ADDRESS = N'TCP://DWH:4022'

GO

CREATE ENDPOINT ODSEndPoint

STATE = STARTED

AS TCP (LISTENER_PORT = 4022)

FOR SERVICE_BROKER (

AUTHENTICATION = WINDOWS,

ENCRYPTION = DISABLED)

GO

SEND A MESSAGE USING THE FOLLOWING:

Declare @.ConversationHandle uniqueidentifier

Begin Transaction

Begin Dialog @.ConversationHandle

From Service [MyInitiatorService]

To Service 'MyTargetService'

On Contract [MyContract]

With Encryption = Off,

Lifetime = 600;

Send on Conversation @.ConversationHandle

Message Type [MyMessage] (N'This is a my message')

End Conversation @.ConversationHandle

Commit

Select GET_TRANSMISSION_STATUS(@.ConversationHandle)

I've done a bit more in trying to resolve the issue and I'm more confused than ever...

As per the Service Broker Routing article on MSDN I have removed the route from the database of the target server and created it in MSDB instead. After doing that the message now remains in the transmission queue of the sending server but without any error (transmission_status is blank). However when I look at the summary report of Service Broker on the sending server under #Messages in Transmission Queue it shows 2 messages and “MyInitiatorService(Non existent service)” in the key to the graph. If there was a problem with the service why would it not show the error in the transmission queue, and what is the problem with the service?

|||I don't know what routing article you mention, but you should definitely have a route both on the sending side as well as on the receiving side - in the databases, not in MSDB.

Also, take out the END CONVERSATION after you have send. End conversation kills the conversation and discards un-send messages. That's probably why you don't see a message in the sys.transmission_queue.

Niels|||

Most likely your message reaches the target, it gets denied access on the service (since you use unsecure dialogs and you don't grant SEND permission to [Public]), the error comes back and then the dialog gets deleted, since you already ended it.

1. Grant SEND permission to [Public] on the target service
2. Don't end the dialog on the initiator side prematurely

HTH,
~ Remus

|||

BTW, you could try following the steps from this article to identify the problem: http://blogs.msdn.com/remusrusanu/archive/2005/12/20/506221.aspx

HTH,
~ Remus

|||

Niels, End conversation does not discard pending messages. However, once you have closed the conversation on your end, you will no longer be able to receive response messages, including errors sent back by target (eg> sender does not have permission to send to this target service).

Flamin, therefore you should not end conversation at the initiator until you've confirmed that it has been delivered to the target service.

Rushi

|||

Thanks for the clarification on End Conversation, I didn’t know that ending the conversation would block errors too. As soon as I removed the End Conversation I received a permissions error. As you suspected Remus the problem was due to a lack of send permissions on the service.

|||

Hi Remus,

I am facing problem which is somewhat related to this it will be great if you can help me in resolving it. Actually for me every thing is working fine in the sense i am able to send and receive the messages.

But i see their are so many messages which are stuck up in sys.conversation_endpoints table. All this messages are having state as DI and initiator as 0.

As i am sending number of messages using same queue i am not able to get to the route of the cause due to which messages are getting stuck up.

Even i am ending conversation on initiator end so can that be the reason for the issue.

Please let me know if you need any more information from me.

Thanks

|||

Those are not messages, but conversation endpoints. DI state for is_initiator = 0 means that you receive EndDialog message on the target, but you don't end the target endpoint of the dialog. To completely close, a conversation must be ended by both conversation endpoints (initiator and target). Typicaly this means than wehn the RECEIVE returns a message of type [http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog] you should issue END CONVERSATION on the received handle.

HTH,
~ Remus

|||

Thanks for your suggestions

But the real issue is when and how should i delete those records from target end.

This is how i am sending message

SELECT @.SendService = '//'+@.Pod_ID+'/TransactionQueue',
@.ReceiveService = '//ODS/'+@.Pod_ID+'/TransactionQueue',
@.Contract = '//Contract/TransactionQueue';

BEGIN DIALOG CONVERSATION @.handle
FROM SERVICE @.SendService
TO SERVICE @.ReceiveService
ON CONTRACT @.Contract;

SEND ON CONVERSATION @.handle
MESSAGE TYPE @.xmlMessageType(@.xmlMessage);

END CONVERSATION @.handle;

And this is how i am processing the message on target end

RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;

I am having a code

IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
RETURN 0
END

Which i thought is creating problem. But i see their are no records with this message type in TransactionQueue (user defined queue) and sys.transmission_queue (system queue).

I am still curious to know how can i get rid of those records from conversation_endpoints. As the count is growing like anything.

Just one more question. If solution is ending conversation on target end, which approach should i follow

1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

2: IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

TIA

Prashant

|||

In case 1, you are ending the dialog regardless of the type of message received. If you expect more than one message interaction, there will be no way to receive more messages.

In case 2, you are ending the dialog only when the initiator has closed the dialog and you know for sure, no more messages are expected.

Also, let me warn you that the pattern you are using (which we call fire-and-forget), where the initiator begins a dialog, sends a message and ends the conversation can be problematic for two main reasons:

i) There is no app-level reliability, i.e. without getting a response back, the initiating app will never know whether its message was processed or not.

ii) During development, you will not be able to see error messages sent back by the target.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

Remote messages not working – message vanishes

I need some assistance with getting service broker to work across servers. I have 2 separate servers and I am trying to send a message from one server to the other. No error is generated when sending the message and I get no records in the transmission queue of the sending server, however the message does not arrive on the receiving server. Where is the message going?

Here is the code I use to create the service broker objects that are being used…

RUN THIS ON THE SENDING SERVER:

CREATE MESSAGE TYPE [MyMessage] VALIDATION = NONE

CREATE MESSAGE TYPE [MyResponse] VALIDATION = NONE

GO

CREATE CONTRACT [MyContract] (

MyMessage SENT BY INITIATOR,

MyResponse SENT BY TARGET)

GO

CREATE QUEUE [MyInitiatorQueue] with status = ON

CREATE QUEUE [MyTargetQueue] with status = ON

GO

CREATE SERVICE [MyInitiatorService] ON QUEUE [MyInitiatorQueue]

GO

CREATE ROUTE [RouteToODS]

WITH

SERVICE_NAME = N'MyTargetService',

BROKER_INSTANCE = '1BB213E2-67A7-4059-BAF8-D9B5F31E358E',

ADDRESS = N'TCP://CONSULT01:4022'

GO

CREATE ENDPOINT DWHEndPoint

STATE = STARTED

AS TCP (LISTENER_PORT = 4022)

FOR SERVICE_BROKER (

AUTHENTICATION = WINDOWS,

ENCRYPTION = DISABLED)

GO

RUN THIS ON THE RECEIVING SERVER:

CREATE MESSAGE TYPE [MyMessage] VALIDATION = NONE

CREATE MESSAGE TYPE [MyResponse] VALIDATION = NONE

GO

CREATE CONTRACT [MyContract] (

MyMessage SENT BY INITIATOR,

MyResponse SENT BY TARGET)

GO

CREATE QUEUE [MyInitiatorQueue] with status = ON

CREATE QUEUE [MyTargetQueue] with status = ON

GO

CREATE SERVICE [MyTargetService] ON QUEUE [MyTargetQueue] ([MyContract])

GO

CREATE ROUTE [RouteToDWH]

WITH

SERVICE_NAME = N'MyInitiatorService',

BROKER_INSTANCE = 'F0BF4E80-704E-4CFE-80FC-637A1EC128C5',

ADDRESS = N'TCP://DWH:4022'

GO

CREATE ENDPOINT ODSEndPoint

STATE = STARTED

AS TCP (LISTENER_PORT = 4022)

FOR SERVICE_BROKER (

AUTHENTICATION = WINDOWS,

ENCRYPTION = DISABLED)

GO

SEND A MESSAGE USING THE FOLLOWING:

Declare @.ConversationHandle uniqueidentifier

Begin Transaction

Begin Dialog @.ConversationHandle

From Service [MyInitiatorService]

To Service 'MyTargetService'

On Contract [MyContract]

With Encryption = Off,

Lifetime = 600;

Send on Conversation @.ConversationHandle

Message Type [MyMessage] (N'This is a my message')

End Conversation @.ConversationHandle

Commit

Select GET_TRANSMISSION_STATUS(@.ConversationHandle)

I've done a bit more in trying to resolve the issue and I'm more confused than ever...

As per the Service Broker Routing article on MSDN I have removed the route from the database of the target server and created it in MSDB instead. After doing that the message now remains in the transmission queue of the sending server but without any error (transmission_status is blank). However when I look at the summary report of Service Broker on the sending server under #Messages in Transmission Queue it shows 2 messages and “MyInitiatorService(Non existent service)” in the key to the graph. If there was a problem with the service why would it not show the error in the transmission queue, and what is the problem with the service?

|||I don't know what routing article you mention, but you should definitely have a route both on the sending side as well as on the receiving side - in the databases, not in MSDB.

Also, take out the END CONVERSATION after you have send. End conversation kills the conversation and discards un-send messages. That's probably why you don't see a message in the sys.transmission_queue.

Niels|||

Most likely your message reaches the target, it gets denied access on the service (since you use unsecure dialogs and you don't grant SEND permission to [Public]), the error comes back and then the dialog gets deleted, since you already ended it.

1. Grant SEND permission to [Public] on the target service
2. Don't end the dialog on the initiator side prematurely

HTH,
~ Remus

|||

BTW, you could try following the steps from this article to identify the problem: http://blogs.msdn.com/remusrusanu/archive/2005/12/20/506221.aspx

HTH,
~ Remus

|||

Niels, End conversation does not discard pending messages. However, once you have closed the conversation on your end, you will no longer be able to receive response messages, including errors sent back by target (eg> sender does not have permission to send to this target service).

Flamin, therefore you should not end conversation at the initiator until you've confirmed that it has been delivered to the target service.

Rushi

|||

Thanks for the clarification on End Conversation, I didn’t know that ending the conversation would block errors too. As soon as I removed the End Conversation I received a permissions error. As you suspected Remus the problem was due to a lack of send permissions on the service.

|||

Hi Remus,

I am facing problem which is somewhat related to this it will be great if you can help me in resolving it. Actually for me every thing is working fine in the sense i am able to send and receive the messages.

But i see their are so many messages which are stuck up in sys.conversation_endpoints table. All this messages are having state as DI and initiator as 0.

As i am sending number of messages using same queue i am not able to get to the route of the cause due to which messages are getting stuck up.

Even i am ending conversation on initiator end so can that be the reason for the issue.

Please let me know if you need any more information from me.

Thanks

|||

Those are not messages, but conversation endpoints. DI state for is_initiator = 0 means that you receive EndDialog message on the target, but you don't end the target endpoint of the dialog. To completely close, a conversation must be ended by both conversation endpoints (initiator and target). Typicaly this means than wehn the RECEIVE returns a message of type [http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog] you should issue END CONVERSATION on the received handle.

HTH,
~ Remus

|||

Thanks for your suggestions

But the real issue is when and how should i delete those records from target end.

This is how i am sending message

SELECT @.SendService = '//'+@.Pod_ID+'/TransactionQueue',
@.ReceiveService = '//ODS/'+@.Pod_ID+'/TransactionQueue',
@.Contract = '//Contract/TransactionQueue';

BEGIN DIALOG CONVERSATION @.handle
FROM SERVICE @.SendService
TO SERVICE @.ReceiveService
ON CONTRACT @.Contract;

SEND ON CONVERSATION @.handle
MESSAGE TYPE @.xmlMessageType(@.xmlMessage);

END CONVERSATION @.handle;

And this is how i am processing the message on target end

RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;

I am having a code

IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
RETURN 0
END

Which i thought is creating problem. But i see their are no records with this message type in TransactionQueue (user defined queue) and sys.transmission_queue (system queue).

I am still curious to know how can i get rid of those records from conversation_endpoints. As the count is growing like anything.

Just one more question. If solution is ending conversation on target end, which approach should i follow

1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

2: IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

TIA

Prashant

|||

In case 1, you are ending the dialog regardless of the type of message received. If you expect more than one message interaction, there will be no way to receive more messages.

In case 2, you are ending the dialog only when the initiator has closed the dialog and you know for sure, no more messages are expected.

Also, let me warn you that the pattern you are using (which we call fire-and-forget), where the initiator begins a dialog, sends a message and ends the conversation can be problematic for two main reasons:

i) There is no app-level reliability, i.e. without getting a response back, the initiating app will never know whether its message was processed or not.

ii) During development, you will not be able to see error messages sent back by the target.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

Remote messages not working – message vanishes

I need some assistance with getting service broker to work across servers. I have 2 separate servers and I am trying to send a message from one server to the other. No error is generated when sending the message and I get no records in the transmission queue of the sending server, however the message does not arrive on the receiving server. Where is the message going?

Here is the code I use to create the service broker objects that are being used…

RUN THIS ON THE SENDING SERVER:

CREATE MESSAGE TYPE [MyMessage] VALIDATION = NONE

CREATE MESSAGE TYPE [MyResponse] VALIDATION = NONE

GO

CREATE CONTRACT [MyContract] (

MyMessage SENT BY INITIATOR,

MyResponse SENT BY TARGET)

GO

CREATE QUEUE [MyInitiatorQueue] with status = ON

CREATE QUEUE [MyTargetQueue] with status = ON

GO

CREATE SERVICE [MyInitiatorService] ON QUEUE [MyInitiatorQueue]

GO

CREATE ROUTE [RouteToODS]

WITH

SERVICE_NAME = N'MyTargetService',

BROKER_INSTANCE = '1BB213E2-67A7-4059-BAF8-D9B5F31E358E',

ADDRESS = N'TCP://CONSULT01:4022'

GO

CREATE ENDPOINT DWHEndPoint

STATE = STARTED

AS TCP (LISTENER_PORT = 4022)

FOR SERVICE_BROKER (

AUTHENTICATION = WINDOWS,

ENCRYPTION = DISABLED)

GO

RUN THIS ON THE RECEIVING SERVER:

CREATE MESSAGE TYPE [MyMessage] VALIDATION = NONE

CREATE MESSAGE TYPE [MyResponse] VALIDATION = NONE

GO

CREATE CONTRACT [MyContract] (

MyMessage SENT BY INITIATOR,

MyResponse SENT BY TARGET)

GO

CREATE QUEUE [MyInitiatorQueue] with status = ON

CREATE QUEUE [MyTargetQueue] with status = ON

GO

CREATE SERVICE [MyTargetService] ON QUEUE [MyTargetQueue] ([MyContract])

GO

CREATE ROUTE [RouteToDWH]

WITH

SERVICE_NAME = N'MyInitiatorService',

BROKER_INSTANCE = 'F0BF4E80-704E-4CFE-80FC-637A1EC128C5',

ADDRESS = N'TCP://DWH:4022'

GO

CREATE ENDPOINT ODSEndPoint

STATE = STARTED

AS TCP (LISTENER_PORT = 4022)

FOR SERVICE_BROKER (

AUTHENTICATION = WINDOWS,

ENCRYPTION = DISABLED)

GO

SEND A MESSAGE USING THE FOLLOWING:

Declare @.ConversationHandle uniqueidentifier

Begin Transaction

Begin Dialog @.ConversationHandle

From Service [MyInitiatorService]

To Service 'MyTargetService'

On Contract [MyContract]

With Encryption = Off,

Lifetime = 600;

Send on Conversation @.ConversationHandle

Message Type [MyMessage] (N'This is a my message')

End Conversation @.ConversationHandle

Commit

Select GET_TRANSMISSION_STATUS(@.ConversationHandle)

I've done a bit more in trying to resolve the issue and I'm more confused than ever...

As per the Service Broker Routing article on MSDN I have removed the route from the database of the target server and created it in MSDB instead. After doing that the message now remains in the transmission queue of the sending server but without any error (transmission_status is blank). However when I look at the summary report of Service Broker on the sending server under #Messages in Transmission Queue it shows 2 messages and “MyInitiatorService(Non existent service)” in the key to the graph. If there was a problem with the service why would it not show the error in the transmission queue, and what is the problem with the service?

|||I don't know what routing article you mention, but you should definitely have a route both on the sending side as well as on the receiving side - in the databases, not in MSDB.

Also, take out the END CONVERSATION after you have send. End conversation kills the conversation and discards un-send messages. That's probably why you don't see a message in the sys.transmission_queue.

Niels|||

Most likely your message reaches the target, it gets denied access on the service (since you use unsecure dialogs and you don't grant SEND permission to [Public]), the error comes back and then the dialog gets deleted, since you already ended it.

1. Grant SEND permission to [Public] on the target service
2. Don't end the dialog on the initiator side prematurely

HTH,
~ Remus

|||

BTW, you could try following the steps from this article to identify the problem: http://blogs.msdn.com/remusrusanu/archive/2005/12/20/506221.aspx

HTH,
~ Remus

|||

Niels, End conversation does not discard pending messages. However, once you have closed the conversation on your end, you will no longer be able to receive response messages, including errors sent back by target (eg> sender does not have permission to send to this target service).

Flamin, therefore you should not end conversation at the initiator until you've confirmed that it has been delivered to the target service.

Rushi

|||

Thanks for the clarification on End Conversation, I didn’t know that ending the conversation would block errors too. As soon as I removed the End Conversation I received a permissions error. As you suspected Remus the problem was due to a lack of send permissions on the service.

|||

Hi Remus,

I am facing problem which is somewhat related to this it will be great if you can help me in resolving it. Actually for me every thing is working fine in the sense i am able to send and receive the messages.

But i see their are so many messages which are stuck up in sys.conversation_endpoints table. All this messages are having state as DI and initiator as 0.

As i am sending number of messages using same queue i am not able to get to the route of the cause due to which messages are getting stuck up.

Even i am ending conversation on initiator end so can that be the reason for the issue.

Please let me know if you need any more information from me.

Thanks

|||

Those are not messages, but conversation endpoints. DI state for is_initiator = 0 means that you receive EndDialog message on the target, but you don't end the target endpoint of the dialog. To completely close, a conversation must be ended by both conversation endpoints (initiator and target). Typicaly this means than wehn the RECEIVE returns a message of type [http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog] you should issue END CONVERSATION on the received handle.

HTH,
~ Remus

|||

Thanks for your suggestions

But the real issue is when and how should i delete those records from target end.

This is how i am sending message

SELECT @.SendService = '//'+@.Pod_ID+'/TransactionQueue',
@.ReceiveService = '//ODS/'+@.Pod_ID+'/TransactionQueue',
@.Contract = '//Contract/TransactionQueue';

BEGIN DIALOG CONVERSATION @.handle
FROM SERVICE @.SendService
TO SERVICE @.ReceiveService
ON CONTRACT @.Contract;

SEND ON CONVERSATION @.handle
MESSAGE TYPE @.xmlMessageType(@.xmlMessage);

END CONVERSATION @.handle;

And this is how i am processing the message on target end

RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;

I am having a code

IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
RETURN 0
END

Which i thought is creating problem. But i see their are no records with this message type in TransactionQueue (user defined queue) and sys.transmission_queue (system queue).

I am still curious to know how can i get rid of those records from conversation_endpoints. As the count is growing like anything.

Just one more question. If solution is ending conversation on target end, which approach should i follow

1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

2: IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

TIA

Prashant

|||

In case 1, you are ending the dialog regardless of the type of message received. If you expect more than one message interaction, there will be no way to receive more messages.

In case 2, you are ending the dialog only when the initiator has closed the dialog and you know for sure, no more messages are expected.

Also, let me warn you that the pattern you are using (which we call fire-and-forget), where the initiator begins a dialog, sends a message and ends the conversation can be problematic for two main reasons:

i) There is no app-level reliability, i.e. without getting a response back, the initiating app will never know whether its message was processed or not.

ii) During development, you will not be able to see error messages sent back by the target.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

Remote messages not working – message vanishes

I need some assistance with getting service broker to work across servers. I have 2 separate servers and I am trying to send a message from one server to the other. No error is generated when sending the message and I get no records in the transmission queue of the sending server, however the message does not arrive on the receiving server. Where is the message going?

Here is the code I use to create the service broker objects that are being used…

RUN THIS ON THE SENDING SERVER:

CREATE MESSAGE TYPE [MyMessage] VALIDATION = NONE

CREATE MESSAGE TYPE [MyResponse] VALIDATION = NONE

GO

CREATE CONTRACT [MyContract] (

MyMessage SENT BY INITIATOR,

MyResponse SENT BY TARGET)

GO

CREATE QUEUE [MyInitiatorQueue] with status = ON

CREATE QUEUE [MyTargetQueue] with status = ON

GO

CREATE SERVICE [MyInitiatorService] ON QUEUE [MyInitiatorQueue]

GO

CREATE ROUTE [RouteToODS]

WITH

SERVICE_NAME = N'MyTargetService',

BROKER_INSTANCE = '1BB213E2-67A7-4059-BAF8-D9B5F31E358E',

ADDRESS = N'TCP://CONSULT01:4022'

GO

CREATE ENDPOINT DWHEndPoint

STATE = STARTED

AS TCP (LISTENER_PORT = 4022)

FOR SERVICE_BROKER (

AUTHENTICATION = WINDOWS,

ENCRYPTION = DISABLED)

GO

RUN THIS ON THE RECEIVING SERVER:

CREATE MESSAGE TYPE [MyMessage] VALIDATION = NONE

CREATE MESSAGE TYPE [MyResponse] VALIDATION = NONE

GO

CREATE CONTRACT [MyContract] (

MyMessage SENT BY INITIATOR,

MyResponse SENT BY TARGET)

GO

CREATE QUEUE [MyInitiatorQueue] with status = ON

CREATE QUEUE [MyTargetQueue] with status = ON

GO

CREATE SERVICE [MyTargetService] ON QUEUE [MyTargetQueue] ([MyContract])

GO

CREATE ROUTE [RouteToDWH]

WITH

SERVICE_NAME = N'MyInitiatorService',

BROKER_INSTANCE = 'F0BF4E80-704E-4CFE-80FC-637A1EC128C5',

ADDRESS = N'TCP://DWH:4022'

GO

CREATE ENDPOINT ODSEndPoint

STATE = STARTED

AS TCP (LISTENER_PORT = 4022)

FOR SERVICE_BROKER (

AUTHENTICATION = WINDOWS,

ENCRYPTION = DISABLED)

GO

SEND A MESSAGE USING THE FOLLOWING:

Declare @.ConversationHandle uniqueidentifier

Begin Transaction

Begin Dialog @.ConversationHandle

From Service [MyInitiatorService]

To Service 'MyTargetService'

On Contract [MyContract]

With Encryption = Off,

Lifetime = 600;

Send on Conversation @.ConversationHandle

Message Type [MyMessage] (N'This is a my message')

End Conversation @.ConversationHandle

Commit

Select GET_TRANSMISSION_STATUS(@.ConversationHandle)

I've done a bit more in trying to resolve the issue and I'm more confused than ever...

As per the Service Broker Routing article on MSDN I have removed the route from the database of the target server and created it in MSDB instead. After doing that the message now remains in the transmission queue of the sending server but without any error (transmission_status is blank). However when I look at the summary report of Service Broker on the sending server under #Messages in Transmission Queue it shows 2 messages and “MyInitiatorService(Non existent service)” in the key to the graph. If there was a problem with the service why would it not show the error in the transmission queue, and what is the problem with the service?

|||I don't know what routing article you mention, but you should definitely have a route both on the sending side as well as on the receiving side - in the databases, not in MSDB.

Also, take out the END CONVERSATION after you have send. End conversation kills the conversation and discards un-send messages. That's probably why you don't see a message in the sys.transmission_queue.

Niels|||

Most likely your message reaches the target, it gets denied access on the service (since you use unsecure dialogs and you don't grant SEND permission to [Public]), the error comes back and then the dialog gets deleted, since you already ended it.

1. Grant SEND permission to [Public] on the target service
2. Don't end the dialog on the initiator side prematurely

HTH,
~ Remus

|||

BTW, you could try following the steps from this article to identify the problem: http://blogs.msdn.com/remusrusanu/archive/2005/12/20/506221.aspx

HTH,
~ Remus

|||

Niels, End conversation does not discard pending messages. However, once you have closed the conversation on your end, you will no longer be able to receive response messages, including errors sent back by target (eg> sender does not have permission to send to this target service).

Flamin, therefore you should not end conversation at the initiator until you've confirmed that it has been delivered to the target service.

Rushi

|||

Thanks for the clarification on End Conversation, I didn’t know that ending the conversation would block errors too. As soon as I removed the End Conversation I received a permissions error. As you suspected Remus the problem was due to a lack of send permissions on the service.

|||

Hi Remus,

I am facing problem which is somewhat related to this it will be great if you can help me in resolving it. Actually for me every thing is working fine in the sense i am able to send and receive the messages.

But i see their are so many messages which are stuck up in sys.conversation_endpoints table. All this messages are having state as DI and initiator as 0.

As i am sending number of messages using same queue i am not able to get to the route of the cause due to which messages are getting stuck up.

Even i am ending conversation on initiator end so can that be the reason for the issue.

Please let me know if you need any more information from me.

Thanks

|||

Those are not messages, but conversation endpoints. DI state for is_initiator = 0 means that you receive EndDialog message on the target, but you don't end the target endpoint of the dialog. To completely close, a conversation must be ended by both conversation endpoints (initiator and target). Typicaly this means than wehn the RECEIVE returns a message of type [http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog] you should issue END CONVERSATION on the received handle.

HTH,
~ Remus

|||

Thanks for your suggestions

But the real issue is when and how should i delete those records from target end.

This is how i am sending message

SELECT @.SendService = '//'+@.Pod_ID+'/TransactionQueue',
@.ReceiveService = '//ODS/'+@.Pod_ID+'/TransactionQueue',
@.Contract = '//Contract/TransactionQueue';

BEGIN DIALOG CONVERSATION @.handle
FROM SERVICE @.SendService
TO SERVICE @.ReceiveService
ON CONTRACT @.Contract;

SEND ON CONVERSATION @.handle
MESSAGE TYPE @.xmlMessageType(@.xmlMessage);

END CONVERSATION @.handle;

And this is how i am processing the message on target end

RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;

I am having a code

IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
RETURN 0
END

Which i thought is creating problem. But i see their are no records with this message type in TransactionQueue (user defined queue) and sys.transmission_queue (system queue).

I am still curious to know how can i get rid of those records from conversation_endpoints. As the count is growing like anything.

Just one more question. If solution is ending conversation on target end, which approach should i follow

1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

2: IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

TIA

Prashant

|||

In case 1, you are ending the dialog regardless of the type of message received. If you expect more than one message interaction, there will be no way to receive more messages.

In case 2, you are ending the dialog only when the initiator has closed the dialog and you know for sure, no more messages are expected.

Also, let me warn you that the pattern you are using (which we call fire-and-forget), where the initiator begins a dialog, sends a message and ends the conversation can be problematic for two main reasons:

i) There is no app-level reliability, i.e. without getting a response back, the initiating app will never know whether its message was processed or not.

ii) During development, you will not be able to see error messages sent back by the target.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.

|||

Prashant wrote:


1: RECEIVE TOP(1) @.xmlMessage = message_body,
@.handle = conversation_handle,
@.message_type = message_type_name
FROM TransactionQueue;
END CONVERSATION @.handle;

Here you are ending the dialog regardless of the type of message being received. If you expect more than a single message to be received on the same dialog, this would be incorrect.

Prashant wrote:


IF @.message_type = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @.handle;
RETURN 0
END

Here you expect the initiator to close the dialog first and then the target closes the dialog upon receiving the end-dialog message. This seems more appropriate if you will have multiple messages on the dialog and the initiator decides when it is done sending messages. Remember, when the initiator ends a dialog, there is no way for it to know if its last message was processed or not.