Showing posts with label messages. Show all posts
Showing posts with label messages. Show all posts

Tuesday, March 20, 2012

conversation groups and processing in order on the target end

Is there any way to ensure that messages sent on different dialogs have the same conversation group id on the target queue? I was attempting to set the conversation group id on the dialog before sending but learned that this only works on the initator end.

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=174976&SiteID=1

I have messages that could be sent from different applications (and at slightly different times) that need to processed exclusively (i.e. have the same conversation group id).

Message ordering is guaranteed within a conversation. Is there any reason that stops you from sending all messages on the same conversation?

HTH,
~ Remus

|||Thanks for the reply - Yes, the sending of messages will be distributed and at different times. i.e. 3 different applications will send messages to the same queue. The messages have to be processed exclusively I tried using one queue as both the initiator and target but the converation group IDs were still different. The move conversation command works but only after messages have been received at the target queue.
|||

Having the conversation from one queue to the same queue does not help, as you noticed, the initiator and target conversation don't share the conversation group. The behavior of conversations that are with local (or event the same) service/queues is in every respect the same as conversations that are with remote services/queues.

But in general, trying to use the conversation group to achieve ordering will get you nowhere. Conversation groups only control what messages can be received by a transaction. That is, they're only relevant to locking. Even if you manage to move all three conversations into the same group and all three messages will be present in the queue, the RECEIVE verb will return them in random order! The messages are guaranteed to be in order within a conversation, not within a group. Actually, you can check the RECEIVE verb execution query plan in the SQL Management Studio and you'll see that it has an ORDER BY clause. This will sort the resultset (a.k.a the messages received) by conversation_handle (among other columns), which is a GUID, so basically the order of conversations within a group is random.

The only way to achieve order is to use one single conversation and send all messages on it. It doesn't matter if they are sent at different times, they will be RECEIVEd in the order sent.

The very problem of preserving order between 3 messages sent from 3 distributed locations is, in my opinion, unsolvable. 3 distributed locations means 3 distinct local times. Which is the authoritative time between them? I.e. if message 'two' was sent one minute after message 'one', but the time on location 'two' is two minutes behind, which message should be considered as sent first? Or if 2 of the 3 messages are sent at identical time 05:10:00 AM, which one was sent first? Or what if message one was sent fine, but the machine hosting location two was destroyed by a suden burst of cosmic rays just before message 'two' being sent, and then message 'three' was sent fine, is message 'three' really message 'three' or is message 'two'?
I only see this problem resolvable if the messages are sent using a primitive that serializes the messages (i.e. the conversation).

Also keep in mind that even if you achieve order by using a single conversation, you still won't be guaranteed that you'll RECEIVE all 3 messages at once (in one single RECEIVE resultset). Messages are RECEIVEd as they show up in the queue, so is perfetcly possible to RECEIVE message 'one' and 'two' while message 'three' is still in traffic.

If you can give some more details on what are you trying to do, I feel we can probably think of a way to achieve what you need.

HTH,
~ Remus

|||

Thanks again for the quick reply

I think I may have phrased the problem incorrectly. I only need the messages in a single conversation to be ordered, but I need for the messages in the three different conversations to be processed exclusively (The processing of the messages will be distributed as well). Unfortunately I cannot send all the messages in a single conversation, so I though I could just designate them to a single conversation group so that only one message from any of the three conversations could be processed at one time.

Any suggestions?

|||You can put the three dialogs in the same conversation group but you will need to do it at the target end when you receive the messages - using MOVE CONVERSATION. I don't know of a practical way to do this. I generally send messages out on different dialogs in the same conversation group so the responses are received together. For example, you could have one of your dialogs send a message to the target and when you receive the message on the target queue, open two new dialogs in the same conversation group as the received message and have those two dialogs send out request messages to get the data back. Pretty convoluted but it should work.|||

You can also add an extra message to your conversation. This message is sent first and contains some form of tag or Id based on which when the target receives this first message, it moves the target conversation endpoint into an appropiate group.

So the initiator does normal BEGIN DIALOG, followed by two SEND (one for the tag/id and one for the real payload). The target receives messages normally in a loop, but reacts differently to the two message types:
- if the message is a tag/id message, it finds the appropiate group and moves the conversation into that group
- if the message is normal payload it process it normally, assured that is the only one processing this group

HTH,
~ Remus

Conversation Groups

I'm having some troubles with conversation groups. I need to send two messages on the same conversation group so I have the following in my SP....

BEGIN DIALOG CONVERSATION @.providerConversationHandle
FROM SERVICE [ProviderDataService]
TO SERVICE 'CalculatedDataService'
ON CONTRACT [ProviderDataContract]
WITH ENCRYPTION = OFF
, LIFETIME = 600;

BEGIN DIALOG CONVERSATION @.curveConversationHandle
FROM SERVICE [ProviderDataService]
TO SERVICE 'CalculatedDataService'
ON CONTRACT [ProviderDataContract]
WITH RELATED_CONVERSATION = @.providerConversationHandle
, ENCRYPTION = OFF
, LIFETIME = 600;

SEND ON CONVERSATION @.providerConversationHandle
MESSAGE TYPE [ProviderDataMessage] ( @.providerMessage );

SEND ON CONVERSATION @.curveConversationHandle
MESSAGE TYPE [ProviderCurveMessage] ( @.curveMessage );

When I query the queue I see two messages, but they don't have the same conversation_group_id.

Any ideas?

Thanks.

Hello Ian,

The conversation group is a locking primitive. Conversations in the same group are locked together, so that any transaction is guaranteed that is the only transaction processing messages on the current group.

As such, conversation groups are pertinent only for the site declaring the group. The group information does not travel with the message to the far side. The two conversations are related, but only in the SENDER's side. If you actually send back a reply on each dialog, then the replies will have the same conversation_group_id.

If the receiver wants to group dialogs, it can use MOVE CONVERSATION to do it, based on it's own locking policies.

Typically apps receive a message and begin new dialogs related to the dialog on which the message was received, not starting two new related dialogs (of course, the can be valid scenarios on for the later case as well!).

HTH,

~ Remus

|||

Thanks for the information.

So if I read you right conversation groups don't allow the receiver to "group" messages together. Are there any good pieces of sample code that show conversation groups in action? all I have seen so far are repeats of the BOL examples.

In my scenario I have two related messages and it is important that the receiving end of the dialog can retrieve and process both my messages together - so how would I go about achieving this?

Thanks

Ian

|||

You should send them both on the same dialog, instead of beginning separate dialogs for each message.

Note that this will allow the message to be received together, but will not guarantee it. The receiver service can still see only the first message while the second is still in traffic.

From my understanding of you example, what you actually looking for is to send 2 parameters to a calculationservice, right? And I assume the 'CalculateDataService' needs both of these parameters to do the actual calculation.

The easiest solution is to group both parameters on one single message and send one message instead of two. The XML and XPath support in the server make both composing the one message from two parts and retrieveing the separate parts on the receiver side easy, if you parameter values can be converted to text (xml nodes).

Often is the case that the two parameters are not available at the same moment, so the sender would prefer to send them separately. In this case you must have a state on the receiver. A table that uses the conversation_group_id as the key and stores the received @.providerMessage and/or @.curveMessage parameters. When the first message is received, the parameter (whichever is) is stored on the table. When the second message is received, the service will find the first parameter in the table and can now do the calculation and respond to the sender.

HTH,

~ Remus

|||

Thanks for the suggestions.

I want to keep my messages seperate as they are pretty large and I don't want the performance overhead of joining and spliting the data, so I guess I will have to look into your suggestions regarding state.

Thanks again.

Ian

|||

Hi Remus

Can you get this explained in BOL.

I couldn't find anything that explained that conversation groups only apply to the initiator side of the dialog. This does seem to be a recurring question

Cheers

|||

That's not in BOL because it's not true. Conversation groups can apply to either the initiator or the target or both. The issue here is that a conversation group is limited to a single queue. The means you can put conversations into a conversation group on the initiator but the conversation group id is not sent over the network to the target. You can also put conversations into a conversation group on the target queue also but this is independent of any conversation groups that you may have set up on the initiator. The conversation group is primarily used for a locking context for SSB commands. SEND and RECEIVE commands can't span queues in a single command so a lock that locks conversations on two different queues doesn't make sense.

Conversation groups aren't sent along with messages from the initiator to target becausethere's no way for the sender of the message to know whether the targets of the conversations in the group are in the same queue. In fact the destination queues can be changed around by the deployer so in general, the conversation initiator has no knowledge of the queue configuration of the target.

|||

Ok so I'm new to SB and what I got from BOL was that

1. conversation groups can be used to group conversations.

2. the conversation group can be specified in the begin dialog so conversations don't have to be intiated at the same time

What isn't in BOL is that even if you group conversations on the initiator, they can not be received from the queue of the target service in these groups.

This was what I was expecting. To be able to send messages from triggers to a service, and then use the RECEIVE TOP (x) to take x of these messages off the target queue and process them. However what it seems is that the RECEIVE statement only returns a conversation and so I have to do the RECEIVE statement x times to get a the BULK set of messages to process.

As has been mentioned when repsonses errors come back to the Initiator queue I can use 1 RECEIVE statement to get a bulk set of messages.

I hope that clarifies the confusion I fell into that I would like in BOL, unless I am wrong again (more than likely).

|||If you want to be anle to receive a bunch of messages at a time on the target side, you should put them into the same dialog. This not only allows you to get the efficiencies related to receiving multiple messages at a time, it also reduces the number of dialogs used and this has very positive performance benefits also. The down side is that all the messages will have to be processed on a single thread but that's the same behavior you would have gotten if you put all the dialogs into the same conversation group because the conversation group is locked when a message is received on any dialog in the group. If you want three threads to receive messages then you need three dialogs. There's a bigger discussion of this here: http://blogs.msdn.com/rogerwolterblog/archive/2006/05/20/602938.aspx

Conversation Groups

I'm having some troubles with conversation groups. I need to send two messages on the same conversation group so I have the following in my SP....

BEGIN DIALOG CONVERSATION @.providerConversationHandle
FROM SERVICE [ProviderDataService]
TO SERVICE 'CalculatedDataService'
ON CONTRACT [ProviderDataContract]
WITH ENCRYPTION = OFF
, LIFETIME = 600;

BEGIN DIALOG CONVERSATION @.curveConversationHandle
FROM SERVICE [ProviderDataService]
TO SERVICE 'CalculatedDataService'
ON CONTRACT [ProviderDataContract]
WITH RELATED_CONVERSATION = @.providerConversationHandle
, ENCRYPTION = OFF
, LIFETIME = 600;

SEND ON CONVERSATION @.providerConversationHandle
MESSAGE TYPE [ProviderDataMessage] ( @.providerMessage );

SEND ON CONVERSATION @.curveConversationHandle
MESSAGE TYPE [ProviderCurveMessage] ( @.curveMessage );

When I query the queue I see two messages, but they don't have the same conversation_group_id.

Any ideas?

Thanks.

Hello Ian,

The conversation group is a locking primitive. Conversations in the same group are locked together, so that any transaction is guaranteed that is the only transaction processing messages on the current group.

As such, conversation groups are pertinent only for the site declaring the group. The group information does not travel with the message to the far side. The two conversations are related, but only in the SENDER's side. If you actually send back a reply on each dialog, then the replies will have the same conversation_group_id.

If the receiver wants to group dialogs, it can use MOVE CONVERSATION to do it, based on it's own locking policies.

Typically apps receive a message and begin new dialogs related to the dialog on which the message was received, not starting two new related dialogs (of course, the can be valid scenarios on for the later case as well!).

HTH,

~ Remus

|||

Thanks for the information.

So if I read you right conversation groups don't allow the receiver to "group" messages together. Are there any good pieces of sample code that show conversation groups in action? all I have seen so far are repeats of the BOL examples.

In my scenario I have two related messages and it is important that the receiving end of the dialog can retrieve and process both my messages together - so how would I go about achieving this?

Thanks

Ian

|||

You should send them both on the same dialog, instead of beginning separate dialogs for each message.

Note that this will allow the message to be received together, but will not guarantee it. The receiver service can still see only the first message while the second is still in traffic.

From my understanding of you example, what you actually looking for is to send 2 parameters to a calculationservice, right? And I assume the 'CalculateDataService' needs both of these parameters to do the actual calculation.

The easiest solution is to group both parameters on one single message and send one message instead of two. The XML and XPath support in the server make both composing the one message from two parts and retrieveing the separate parts on the receiver side easy, if you parameter values can be converted to text (xml nodes).

Often is the case that the two parameters are not available at the same moment, so the sender would prefer to send them separately. In this case you must have a state on the receiver. A table that uses the conversation_group_id as the key and stores the received @.providerMessage and/or @.curveMessage parameters. When the first message is received, the parameter (whichever is) is stored on the table. When the second message is received, the service will find the first parameter in the table and can now do the calculation and respond to the sender.

HTH,

~ Remus

|||

Thanks for the suggestions.

I want to keep my messages seperate as they are pretty large and I don't want the performance overhead of joining and spliting the data, so I guess I will have to look into your suggestions regarding state.

Thanks again.

Ian

|||

Hi Remus

Can you get this explained in BOL.

I couldn't find anything that explained that conversation groups only apply to the initiator side of the dialog. This does seem to be a recurring question

Cheers

|||

That's not in BOL because it's not true. Conversation groups can apply to either the initiator or the target or both. The issue here is that a conversation group is limited to a single queue. The means you can put conversations into a conversation group on the initiator but the conversation group id is not sent over the network to the target. You can also put conversations into a conversation group on the target queue also but this is independent of any conversation groups that you may have set up on the initiator. The conversation group is primarily used for a locking context for SSB commands. SEND and RECEIVE commands can't span queues in a single command so a lock that locks conversations on two different queues doesn't make sense.

Conversation groups aren't sent along with messages from the initiator to target becausethere's no way for the sender of the message to know whether the targets of the conversations in the group are in the same queue. In fact the destination queues can be changed around by the deployer so in general, the conversation initiator has no knowledge of the queue configuration of the target.

|||

Ok so I'm new to SB and what I got from BOL was that

1. conversation groups can be used to group conversations.

2. the conversation group can be specified in the begin dialog so conversations don't have to be intiated at the same time

What isn't in BOL is that even if you group conversations on the initiator, they can not be received from the queue of the target service in these groups.

This was what I was expecting. To be able to send messages from triggers to a service, and then use the RECEIVE TOP (x) to take x of these messages off the target queue and process them. However what it seems is that the RECEIVE statement only returns a conversation and so I have to do the RECEIVE statement x times to get a the BULK set of messages to process.

As has been mentioned when repsonses errors come back to the Initiator queue I can use 1 RECEIVE statement to get a bulk set of messages.

I hope that clarifies the confusion I fell into that I would like in BOL, unless I am wrong again (more than likely).

|||If you want to be anle to receive a bunch of messages at a time on the target side, you should put them into the same dialog. This not only allows you to get the efficiencies related to receiving multiple messages at a time, it also reduces the number of dialogs used and this has very positive performance benefits also. The down side is that all the messages will have to be processed on a single thread but that's the same behavior you would have gotten if you put all the dialogs into the same conversation group because the conversation group is locked when a message is received on any dialog in the group. If you want three threads to receive messages then you need three dialogs. There's a bigger discussion of this here: http://blogs.msdn.com/rogerwolterblog/archive/2006/05/20/602938.aspxsqlsql

Conversation Group Question

I'm trying to use Service Broker to relate a set of messages together and was trying to use a related conversation group id. From what I can gather (looking at other threads) I can't use this.....

Basically, my ideas was.... I have several tables being updated within a database transaction. These tables will have triggers associated with them which send a message to a SB queue detailing the table that has been affected and the key information.

After the database transaction commits, I wanted to retrieve the group of messages in order to identify exactly what happened to the database during the transaction (for business reasons). I don't need necessarily need them in the same order, but do need them grouped by database transaction.

Service Broker seemed to be ideal i.e. the messages wouldn't commit if the database transaction rolled back and I wouldn't be able to access them until the entire transaction was committed........ My only problem is that I don't seem to be able to associate them with each other!!!!

Can anyone help with a way I can do this with Service Broker, or am I just trying to use the wrong technology?

If you can avoid doing the SEND in the trigger but instead do it in the batch executing the updates, then you could use a single dialog for sending all your messages as shown below:

DECLARE @.dh UNIQUEIDENTIFIER;
BEGIN TRANSACTION;
BEGIN DIALOG @.dh ...;
UPDATE TABLE t0 ...;
SEND ON CONVERSATION @.dh ...;
UPDATE TABLE t1 ...;
SEND ON CONVERSATION @.dh...;
...
COMMIT;

If you must do the SEND in the trigger, then you will have to somehow pass the conversation handle of an opened dialog or a conversation group id to bind new dialogs to from your batch to the trigger. I suppose that will involve some sort of temporary table.

Conversation group id question

HI

I have an example ( see below ).

I expect to have all messages sent using this code to have the same group id but they are all different. what I am doing wrong?

Leonid.

DECLARE @.conversationHandle uniqueidentifier

DECLARE @.usergroup uniqueidentifier

select @.usergroup = uid from bvuser where userid = 1

select @.usergroup

Begin Transaction

BEGIN DIALOG @.conversationHandle

FROM SERVICE [BvMainResponseService]

TO SERVICE 'BvMainService'

ON CONTRACT [BvMainContract]

WITH RELATED_CONVERSATION_GROUP = @.usergroup;

-- Send a message on the dialog

SEND ON CONVERSATION @.conversationHandle

MESSAGE TYPE [BvTaskMsg]

(N'Test')

commit

As far as i understand it you expand a conversation group by adding additional dialogs related to the first one:

For example:

DECLARE @.conversationHandle uniqueidentifier

Begin Transaction

BEGIN DIALOG @.conversationHandle

FROM SERVICE [BvMainResponseService]

TO SERVICE 'BvMainService'

ON CONTRACT [BvMainContract]

WITH RELATED_CONVERSATION_GROUP = @.conversationHandle;

-- Send a message on the dialog

SEND ON CONVERSATION @.conversationHandle

MESSAGE TYPE [BvTaskMsg]

(N'Test')

commit

You keep using the conversation handle from the begin dialog to keep the same conversation, i could be mistaken as i have not really tried it , but i think that is the theory anyway.

Thanx

|||

this is from BOL

If related_conversation_group_id does not reference an existing conversation group, the service broker creates a new conversation group with the specified related_conversation_group_id and relates the new dialog to that conversation group.

so as I understand this - new conversation group id is created when BEGIN DIALOG is used for the first time with specified ID, and then ... here is BOL again

Specifies the existing conversation group that the new dialog is added to. When this clause is present, the new dialog will be added to the conversation group specified by related_conversation_group_id.

But obviously I am doing something wrong here becuase it doesn't work as I expect it.

Leonid.

|||

In the test you've shown the conversation should have the same conversation group id. How are you looking up the conversations?

Here is a test script that shows that the related_conversation_group creates conversation in the same group, and the first BEGIN CONVERSATION creates the group itself, just as you expect:

use [tempdb];

go

create queue [testQueue];

create service [testService] on queue [testQueue];

go

create queue [targetQueue];

create service [targetService] on queue [targetQueue] ([DEFAULT]);

go

declare @.cg uniqueidentifier;

declare @.h uniqueidentifier;

select @.cg = newid();

begin dialog conversation @.h

from service [testService]

to service N'targetService', N'current database'

with related_conversation_group = @.cg,

encryption = off;

send on conversation @.h;

begin dialog conversation @.h

from service [testService]

to service N'targetService', N'current database'

with related_conversation_group = @.cg,

encryption = off;

send on conversation @.h;

begin dialog conversation @.h

from service [testService]

to service N'targetService', N'current database'

with related_conversation_group = @.cg,

encryption = off;

send on conversation @.h;

select * from sys.conversation_endpoints where conversation_group_id = @.cg;

HTH,
~ Remus

Monday, March 19, 2012

controlling merge syncronisation at subscriber with ActiveX

Hi,
If I am to use the merge activex control to run syncs at the subscriber, in
what system tables will I find merge history, error messages etc ?
I read in another thread about querying the subscriber prior to attempting a
sync to determine if the subscriber db needed reinitialisation (by comparing
version number values in a user table) - so that active x could flag the
subscription for reinitialisation automatically. Any idea how this would
actually be done ?
It would be great to have the sunscriber db be automatically flagged for
reinitialisation when needed, and not require user input.
Thanks for your help
Darren
query the msmerge_history table in the distribution database on the
subscriber if its a pull.
Hilary Cotter
Looking for a SQL Server replication book?
http://www.nwsu.com/0974973602.html
"Darren Wallace" <darren@.pcresources.com.au> wrote in message
news:e5pPdbNlEHA.3392@.TK2MSFTNGP14.phx.gbl...
> Hi,
> If I am to use the merge activex control to run syncs at the subscriber,
in
> what system tables will I find merge history, error messages etc ?
> I read in another thread about querying the subscriber prior to attempting
a
> sync to determine if the subscriber db needed reinitialisation (by
comparing
> version number values in a user table) - so that active x could flag the
> subscription for reinitialisation automatically. Any idea how this would
> actually be done ?
> It would be great to have the sunscriber db be automatically flagged for
> reinitialisation when needed, and not require user input.
> Thanks for your help
> Darren
>

Sunday, February 19, 2012

Consuming Multiple Messages In Parallel from Multiple Windows Services

Hi Remus

What if I need multiple clients to read (RECEIVE) the same message?

Would it be possible?

Thanks

No.

A message can only be received once. Normally the first RECEIVE statement removes it from the queue, so no other RECEIVE can find the same message.

Also there is no way for the clients to specify the message to be received. With a WHERE clause the RECEIVE statement at most can restrict the result set to a particular conversation, but not to a particular message.

And finally RECEIVE statement is always executing in READ COMMITED isolation level, so two clients cannot receive messages from the same conversation group in different transactions, since each RECEIVE will attempt to place an exclusive lock on the conversation group and only one transaction can have an exclusive lock at any given moment.

HTH,
~ Remus

|||

If you are looking at a publish/subscribe type scenario, where you want messages to be delivered to multiple services, you could implement a service that maintains a list of subscriber services and upon receiving a message, sends a copy out each of its subscribers. See the sample on Remus' blog:

http://blogs.msdn.com/remusrusanu/archive/2005/12/12/502942.aspx

|||

Hi Rushi/Remus

I tested that example, setting the same subscription from two different clients. Then I sent a publication, and read messages.

For what I understand in that example when a client subscribes for a particular publication, his conversationID is saved on a table.

When a publication occurs a procedure sends messages to all subscribers, using that conversationID.

BUT, in case there are two subscriptions and a single client is listening for messages, two identical messages are read by the client.

In case there are two clients listening a lot of confusion, sometimes one client gets two messages, sometimes one, sometimes nothing...

I was expecting , since the conversationID seems to address to a single endpoint, only one message...

|||

Assuming that on a publish/subscribe scenario each client must create a unique subscription, I realize that each client have to create its own queue and service.

The problem is sending messages then.

The initiator should send the same message to all queues, but how? The number of queues created is not defined, is there a way to do it?

Is my theory correct? Or am I on the wrong direction?

Thanks for helping

|||

The subscribers are individual conversations. If they are on the same queue, then you must use the RECEIVE ... FROM queue WHERE conversation_handle = ... syntax to retrieve only the notifications for a given client (subscription).

If you use the RECEIVE w/o a WHERE clause, then the clients will mix the notifications, if they are on the same queue.

In the pub/sub sample at http://blogs.msdn.com/remusrusanu/archive/2005/12/12/502942.aspx the initiator doesn't know nor need to how many clients/queues are there. It will iterate through subscriptions and send a message to each one. Clients can be on the same queue or on different queue, it doesn't matter. The subscription notifications are all reply messages (from target to initiator, since is the client that initiates the subscription), so the pub/sub service does not need to know upfront how many clients are there, it just sends replies on the existing dialogs.

HTH,
~ Remus

|||

Thanks for the clarification Remus.

Now it's working good!

|||

Hi,

I have a couple of questions to make.

How can i trigger notifications to my application ( C#)

without hanging in WaitFor Operation?

It's possible for broker service to call some remote

object that my application provide ?

Can Publish/Subscribe using Broker Service be used

for a low latency notifications (150ms ) max with milions of

messages published per second?

Thanks in advance

Srgio

Consuming Multiple Messages In Parallel from Multiple Windows Services

Hello All,

After hitting limitations in the SQL CLR world that bar us from invoking COM objects we are forced to use windows services to read the messages off the Service Broker Queues.
Unfortunately we loose the auto activation feature in the Queues, but we can still read messages and perform the SQL work under one transaction.

We are going to attempt to take N messages simultaneously from the Queue, though N instances of a windows service. If the messages send to the queue are one message per conversation, will we be able to achieve having N readers take messages off simultaneounsly?

Thank you very much,

Lubomir

P.S. if anyone has a better approach to obtaining the message in "out of sql code" or invoking external (not assemblies stores in SQL server) code libraries, that would be etremely nice to hear. I have thought about invoking a web service through CLR, but that is probably too much overhead - MSMQ seems much more appealing than a web service;

Lubomir,

Retrieving messages from a queue with the RECEIVE statement should be regarded similar with running an UPDATE statement on a table. Multiple clients (Windows Services in you case) can run concurent updates (receives in your case) as long as they don't try to update the same rows (messages in your case). The difference is that in the RECEIVE case there is a built in mechanism to choose what rows should be updated (i.e. what messages should be dequeued) in order to avoid update conflicts. Each RECEIVE will grab the next available (i.e. not locked) conversation group, lock it, and then retrieve (dequeue) messages from conversations in this group. In fact, one can use any of the tools that show query plans (Profiler, Management Studio, Query Analyzer) and ask for the query plan of the RECEIVE in order to understand what this statement does.

So yes, RECEIVE statements can be issued in parallel and they will execute simultaneously.

There is an External Activator sample at you might want to take a look at, http://www.gotdotnet.com/codegallery/codegallery.aspx?id=9f7ae2af-31aa-44dd-9ee8-6b6b6d3d6319.

HTH,
~ Remus

|||Thank you very much for the insight, Remus. The external activator seems rather promising.

Lubomir|||

Thanks

So if I understand well I should build a different conversation for each client, and replicate same messages on different conversation, so that every client gets the message.

But what if the number of clients isn't fixed?

Any suggestion?

|||

Basically this is a Publish/Subscribe scenario. Look at this example at http://blogs.msdn.com/remusrusanu/archive/2005/12/12/502942.aspx and see if you can start building something from it.

HTH,
~ Remus