In this blog, I’ll introduce you to Session Transactions, commonly called Local Transactions. Transacted Sessions enable client applications to group multiple message send and/or receive operations together in single, atomic units. Session Transactions are supported by Solace’s Java, JavaRTO, C, .NET and JMS APIs.
In this post I’ll explain what they are, why to use them, and how to use them. I’ll also describe how a new transaction begins, and the interactions that take place between client applications and the Solace message router. In a future post I’ll demonstrate, using sample code, a client making use of Session Transactions.
What is a Session Transaction?
The Session Transactions feature allows client applications to publish and/or consume a series of messages as one atomic unit. The messages that are published and received in a Transaction are staged on the Solace Message Router.
A transaction must be committed before any message sends or receives are completed.
During a transaction, if for some reason the client is not able to publish or consume all the messages which were part of the atomic unit. The transaction can be cancelled and rolled back (in place of commit) by the client applications. For example, in case of a publishing client, it means none of the messages are delivered to the configured destination, even though some messages may have already reached the Solace Message router (but not delivered to destinations yet).
In case of a consuming client, this would mean none of the messages are consumed, even though some may have reached the consumer listener thread (but not acknowledged).
This Session Transactions can only be used with Guaranteed Messages.
When/Why to Use Session Transactions
A transaction enables an application to coordinate a group of messages for production and consumption, satisfying concurrency and atomicity requirements. Concurrency controls guarantee that two users accessing/modifying/acting on the same data will not be able to interfere with each other. As one of the user has to wait until the other user finished processing. Atomicity controls guarantee that all the steps in Transaction are completed successfully as a group. That is, if any step during the Transaction fails, all other steps must fail also. The use of Transactions makes the design of complex systems easier for the programmer. Some of the major benefits one can achieve from it are as follows:
- Fault Tolerance
- Increased reliability
- Centralized Architecture
- Overall Cost is reduced
How to Use Session Transactions
Applications participate in a transaction by creating a transacted session (or local transaction) and completely control the message delivery by either committing (i.e. publishing all or consuming all) or rolling back (i.e. publishing none or consuming none) the session.
To create a transaction for publishing and/or consuming messages, a client application must first create a Transacted Session within a Solace API Session connected to a Solace Message Router. In the Transacted Session just obtained, the client application can establish a producer (or consumer) flow to publish (or receive) messages in a Transaction.
As messages are produced (or consumed) within a local transaction, Solace tracks the various sends and receives, completing these operations only when the client application issues a call to commit the transaction. If a particular send or receive operation within a transaction fails, an exception is raised. The client application can handle the exception by ignoring it, retrying the operation or rolling back the entire transaction. Otherwise, when a transaction is committed, all its operations are completed. When a transaction is rolled back, all successful operation are cancelled. Once a Transaction is completed, another Transaction automatically begins.
Solace APIs provide methods and function-calls for initiating, committing, or rolling back session transactions.
The client applications can create one or more Transacted Sessions within an existing Session. A transacted Session has exactly one active Transaction. The transaction automatically begins once a Transacted Session is created. There are three broad steps required to make use of Transactions i.e.
- Creating Transacted Sessions and Flow to the Solace Message Router
- Publishing Messages in Transactions or Consuming Messages in Transactions
- Graceful end to the transaction (commit or rollback)
Creating Transacted Sessions
Solace supports creation of one producer flow to publish messages and a maximum of 256 consumer flows to consume messages within a Transacted Session (for details, refer Using Local Transactions in the Solace Messaging APIs Developer Guide).
Note: The blue and red arrows represent publisher and consumer flows.
Publishing Messages in Transactions
Publishing guaranteed Messages in a Transaction requires a producer flow that must be established in the Transacted Session.
As shown in the picture below, the messages published are staged on the Solace Message Router. They are not delivered to their destinations on the Solace Router until the client issues a commit. If the commit is successful, the messages are delivered to their destinations and the staging information is removed.
Consuming Messages in Transactions
Transacted Session consumers operate in the similar fashion as those in a non-Transacted Session. Only difference being that the messages received by consumer are only considered acknowledged when a successful commit occurs for the Transacted Session and subsequently removed from the Solace Message Router. Sending individual acknowledgment for each message received using respective API function calls has no effect on the Transacted Sessions.
When in the middle of a Transaction i.e. before a commit is made, for the messages which are consumed if the following conditions occur, those messages are still successfully committed.
- An administrative action deletes the messages from the spool.
- The TTL on the messages has expired.
Graceful End to the transaction
Messages published and received on a Transaction are staged on the Solace Message Router. The Transaction can end either of the 2 ways:
A) Completed Thru Commit Operation
When a client application commits the transaction the following subsequent actions are taken at the Solace Message Router:
- For Publish Operations, the staged Messages are sent to their destinations (See picture above “Producer Transactions”)
- For Receive Operations, the received Messages are considered acknowledged by the consumers and then removed from the respective endpoints they were spooled to.
B) Cancelled thru a Rollback Operation
When a client applications is not satisfied due to an exception on the Transaction or for any other reason. Instead of completing an active Transaction through a commit, it can rollback the transaction. Under a rollback, following occurs:
Staging information for the Transaction is removed i.e.
- For Publishing Transactions – The Messages published under the Transaction are deleted.
- For Consuming Transactions – The Messages delivered to Consumer remain on the endpoints.
How a New Transaction Begins
A New (or Next) Transaction is automatically generated after the end of the previous Transaction either by Commit or Rollback.
Things to Remember
Following summarizes some key points to remember about session transactions in Solace.
- Transactions are meant only for Guaranteed Messaging.
- Maximum of 256 Messages are allowed in a single transaction.
- Transacted Sessions are only supported for single thread use.
- Maximum of one producer flow allowed in a Transacted Session.
- Maximum of 256 consumer flows allowed in a Transacted Session.
- The Solace API rolls back the Transaction and no automatic re-attempts are made if Transacted Session is closed prior to commit.
- One cannot have an end-to-end transaction encompassing both the production and consumption of the same message.
In this post we have learned about the Session Transaction feature. Covered what is a local transaction, why to use a Session Transaction. We studied transactions in general terms and scenarios where it is most useful. In addition, I listed some important Solace capability and behavioral points. In my next post, I will provide a sample JMS client (producer and consumer) implementation making use of Session Transactions.