Distributed transactions in .NET
Distributed transactions or global transactions allows client applications to include several different sources of data on two or more networked systems in one transaction.
In distributed transactions, a transaction manager coordinates and manages the transaction among two or more resource managers.
Transactions can be either single phase or two-phase commit process. The single-phase commit is a process where only one resource manager participates in the transaction and two-phase commit process is where there are more than one resource manager participating in the transaction. In the two-phase commit process, the transaction manager sends a prepare call to check whether all the resource managers are prepared to commit. When it receives the acknowledgment from all the resource managers, the commit call is issued. Else, a rollback on the whole transaction happens. See Transaction management and support for more details. The resource managers should inform the transaction managers of their participation in the transaction. When the resource manager informs the transaction manager of its participation, the resource manager gets callbacks from the transaction manager when the transaction is going to commit or roll back.
IBM MQ .NET classes already supports distributed transactions in unmanaged and server bindings mode connections. In these modes, IBM MQ .NET classes delegates all its calls to C extended transaction client, which manages the transaction processing on behalf of .NET.
IBM MQ.NET classes now support distributed transactions in managed mode where IBM MQ .NET Classes uses System.Transactions namespace for the distributed transactions support. The System.Transactions infrastructure makes transactional programming simple and efficient by supporting the transactions initiated in all the resource managers including IBM MQ. The IBM MQ .NET application can put and get messages using .NET implicit transaction programming or explicit transaction programming model. In implicit transactions, the transaction boundaries are created by the application program that decides when to commit, rollback (for explicit transactions) or complete the transaction. In explicit transactions, we have to explicitly specify whether you want to commit, roll back, and complete the transaction.
IBM MQ.NET uses Microsoft distributed transaction coordinator (MS DTC) as the transaction manager, which coordinates and manages the transaction between multiple resource managers. IBM MQ is used as the resource manager. Note that we cannot use TLS with XA transactions. You must use CCDT. For more information, see Use the extended transactional client with TLS channels.
IBM MQ.NET follows the X/Open Distributed Transaction Processing (DTP) model. The X/Open Distributed Transaction Processing model is a distributed transaction processing model proposed by the Open Group, a vendor consortium. This model is a standard among most of the commercial vendors in the transaction processing and database domains. Most of the commercial transaction management products support the X/DTP model.
Modes of transaction
Coordinating transactions in various scenarios
- A connection might participate in several transactions, but only one transaction is active at any point of time.
- During a transaction, the MQQueueManager.Disconnect call is honored. In this case the transaction is asked to roll back.
- During a transaction, the MQQueue.Close or MQTopic.Close call is honored. In this case transaction is asked to roll back.
- The transaction boundaries are created by the application program that decides when to commit, rollback (for explicit transactions) or complete (for implicit transactions) the transaction.
- If the client application breaks during a transaction with an unexpected error before issuing a Put or Get call on a queue or topic call, the transaction is rolled back and a MQException is thrown.
- If MQCC_FAILED reason code is returned during a Put or Get call on a queue or Topic call, an MQException is thrown with reason code and the transaction is rolled. If a prepare call has been already issued by the transaction manager, then IBM MQ .NET returns the prepare request by forcibly rolling back the transaction. Then the transaction manager DTC causes a rollback on current work with all the resource managers in current ambient transactions.
- During a transaction involving multiple resource managers if some environmental reason causes the Put or Get call to hang indefinitely, the transaction manager waits until a stipulated time. After the time is out, it causes the rollback of all current work with all the resource managers in current ambient transactions. If this indefinite wait happens during the prepare phase, the transaction manager might timeout or issue an in-doubt call on the resource in which case the transaction is rolled back.
- Applications using transactions must Put or Get messages under SYNC_POINT. If a message Put or Get call is issued under a transactional context that is not under SYNC_POINT, the call fails with MQRC_UNIT_OF_WORK_NOT_STARTED reason code.
Behavioral differences between Managed and Unmanaged Client transaction support using Microsoft.NET System.Transactions namespace
Nested Transactions have a TransactionScope inside another TransactionScope
- IBM MQ .NET fully managed client does support nested TransactionScope
- IBM MQ .NET unmanaged client does not support nested TransactionScope
Dependent Transactions from System.Transactions
- IBM MQ .NET fully managed client does support the dependent transactions facility provided by System.Transactions.
- IBM MQ .NET unmanaged client does not support the dependent transactions facility provided by System.Transactions.
Product Samples
New product samples SimpleXAPut, and SimpleXAGet are available under WebSphere MQ\tools\dotnet\samples\cs\base. The samples are C# applications, which demonstrate using MQPUT and MQGET under Distributed Transactions using SystemTransactions namespace. For more information about these samples, see Creating simple put and get messages within a TransactionScope