Summary: Using transactions to group operations.
Overview A transaction over a space makes a group of operations act as a single unified operation with regards to the space. A transaction is considered successful when all its operations are successful. Aborting a transaction undoes all the operations under its scope. A failed transaction would normally be aborted. Entries manipulated under a transaction are locked to prevent them from being changed by operations that do not belong to the current transaction scope. Using the ReadModifiers, it is possible to control the level of visibility that locked entries have to any external operation that is out of the locking transaction. The time out parameter used in the space operations gives the flexibility to determine how long to wait for a locked entry. Why Use a Transaction? A transaction is normally used to group a sequence of operations that have dependency, or are coupled by business logic to a single operation. Consider the situation where I have a group of entries that are mapped to a single business logic object. Any change to the business logic object has to be synchronized between all the entries. To prevent an inconsistent state which a failure in changing one of the entries might cause, a transaction wrapper to any change to the BL object is a good decision. Creating a Transaction The example below demonstrates a local transaction creation and a simple usage with the transaction object.
ITransaction tx1 = _proxy.CreateLocalTransaction();
...
try
{
...
_proxy.Write(person1, tx1);
_proxy.Update(person2,tx1);
_proxy.Take(person3, tx1);
tx1.Commit();
}
catch(SpaceException se)
{
tx1.Abort();
}
finally
{
tx1.Dispose();
}
Local Transaction The local transaction is created using the space proxy.
ITransaction tx1 = _proxy.CreateLocalTransaction()
A local transaction can be used with a clustered proxy over a cluster as long as all the operations are routed to the same space node in the cluster. When writing an object using a clustered proxy, a space routing field has to be used to verify that all the entries used on the transaction operations are written to the same space instance. If an operation under a transaction is attempting to get to a different cluter member, an exception is thrown. Distributed Transaction The distributed transaction concept is based on the requirement to synchronize transactional operations between multiple hosts (spaces in this case). The distributed transaction manager uses a two phase commit in order to commit the transactions. There is always a risk of ending up with an inconsistent state when using it. Distributed transactions are slower than local transactions, and recommended only in cases where local transaction cannot apply. Distributed transactions are governed by the Distributed Transaction Manager, which is the synchronization point against which, all the members of the transaction are connected and synchronized. The Distributed Transaction Manager is started as a separated process (DistributedTransactionManager.exe), which has to be started separately in order to be used. Once started the the DTM is searched in a similar way that a space is searched on the network, by any proxy that is trying to use its services.
ITransactionManager myTxManager = proxy.Factory.FindJiniTransactionManager();
ITransaction myTransaction = myTxManager.Create();
When commiting a distributed transaction, the time out parameter has to be used.
myTransaction.Commit(timeOut)
The parameter states the amount of time that the proxy waits for the transaction manager to complete the operation. If the time out is passed, but the operation is not completed yet, there is no way to know if the operation was completed successfully or not. A failed commit before the time out has passed, generates an exception. In order to use distributed transactions, the distributed transaction manager has to be explicitly started. Entries Under a Transaction Entries that were changed under a transaction that is not yet committed, are locked for any other changes by other operations that are not under the same transaction. These entries are released for changes, only once the transaction is finished (committed or aborted). Any changes to entries under a transaction are not viewable (for read operations), unless specified. |