Understanding Transactional Messaging


Transactional messaging is the process of sending and receiving messages in transactions. A transaction is a set of one or more messages. Transactional messages are grouped inside a transaction context, which keeps track of the transaction states.

Transaction processing ensures two things: that all messages bundled in a transaction either are delivered together in order or that none of the messages participating in a transaction are sent if there's a failure in transaction. The success of a transaction is called a committed transaction, and the failure of a transaction is called an aborted transaction.

In message queuing, there are two types of transactions: internal and external. In the internal transaction process, the message transfer happens between two queues belonging to a queuing server. On the other hand, an external transaction involves message transfer between a queue and other resources (not related to queuing) such as a database. This chapter discusses internal transactions only.

Using the MessageQueueTransaction Class

The MessageQueueTransaction class represents an internal transaction. This class has a property called Status, which represents the status of the transaction. The status of a transaction is of type MessageQueueTrasactionStatus enumeration type. It has four values: Aborted, Committed, Initialized, and Pending.

The Aborted value represents the transaction has been aborted, and there will be no changes in the current state of the messages. The Committed value indicates that the transaction has been committed and all message were sent as expected. The Initialized value indicates that the transaction has been initialized but not started yet. The Pending value represents that the transaction has been started and is still in process.

Besides the Status property, the MessageQueueTransaction has three methods: Abort, Begin, and Commit. The Abort method rolls back the pending transaction. The Begin method starts a transaction, and the Commit method saves the pending transactions.

To create an internal transaction, you can use the Create method of MessageQueueTransaction, and when you're sure you want to commit or roll back the transaction, you call Commit or Abort methods.

Creating Transactional Queues

Do you remember when you created a new message queue in the Server Explorer using the Create Queue menu option? When you create a queue using the Server Explorer, there's a check box on the dialog box that allows you to create a transactional queue (see Figure 21-6).

click to expand
Figure 21-6: Creating a transactional queue using the Server Explorer

Creating a transactional message queue programmatically is pretty simple. When you use the Create method of MessageQueue, you pass the second argument as true to create a transactional message queue. For example, the following code creates a transactional queue:

 Dim mq as New MessageQueue mq =MessageQueue.Create(".\mcbTransQueue", True) 

Sending and Receiving Transactional Messages

When creating a transactional queue, the Send and Receive methods of MessageQueue take the last argument as the transaction object. Listing 21-9 shows how to send and receive transactional messages. As you can see from this code, the transaction is only committed where there were no errors; otherwise, the transaction is aborted.

Listing 21-9: Sending and Receiving Transactional Messages

start example
 Imports System Imports System.Messaging Module Module1   Sub Main()     'SendTransactionalMessages()     RecieveTransactionalMessages()   End Sub   Public Sub SendTransactionalMessages()     Dim mq As MessageQueue = New MessageQueue()     mq = MessageQueue.Create(".\Private$\mcbTQ", True)     Dim tran As MessageQueueTransaction = _     New MessageQueueTransaction()     Try       tran.Begin()       mq.Send("Body of first message", "Message1", tran)       mq.Send("Body of second message", "Message2", tran)       mq.Send("Body of third message", "Message3", tran)       tran.Commit()       Console.WriteLine("Transaction committed!")     Catch       tran.Abort()       Console.WriteLine("Transaction Aborted!")     End Try   End Sub   Public Sub RecieveTransactionalMessages()     Dim mq As MessageQueue = New MessageQueue()     mq.Path = ".\Private$\mcbTQ"     Dim tran As MessageQueueTransaction = _     New MessageQueueTransaction()     Try       tran.Begin()       Dim messages() As System.Messaging.Message       messages = mq.GetAllMessages()       ' Need a formatter to get the text of the message body.       Dim stringFormatter As System.Messaging.XmlMessageFormatter = _          New System.Messaging.XmlMessageFormatter(New String() _          {"System.String"})       Dim index As Integer       Dim msg As System.Messaging.Message       For index = 0 To messages.Length - 1         messages(index).Formatter = stringFormatter         msg = messages(index)         Console.WriteLine(msg.Label + "," + msg.Body)       Next       tran.Commit()       Console.WriteLine("Transaction committed!")     Catch       tran.Abort()       Console.WriteLine("Transaction Aborted!")     End Try   End Sub End Module 
end example

Tip

Transactional processing is useful when you want to make sure that all messages in a transaction are delivered or none of them are.




Applied ADO. NET(c) Building Data-Driven Solutions
Applied ADO.NET: Building Data-Driven Solutions
ISBN: 1590590732
EAN: 2147483647
Year: 2006
Pages: 214

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net