Tamino API for .NET Version 8.2.2
 —  Tamino API for .NET  —

Processing Transactions

For a general introduction to transaction-oriented programming with Tamino, see also the document Transactions Guide.

When opening a TaminoConnection, you need to specify how commands are to be handled by the Tamino XML Server by using the TaminoConnectionMode enumeration. The enumeration has the following values:

These values specify the scope of a command's transaction.

Additionally, the behavior within a transaction can be specified in more detail. For more information, refer to these sections:

This document comprises the following sections:

Note:
On multithreaded transaction usage: It is the user's responsibility to ensure that multiple threads do not attempt to execute transactional commands simultaneously. In other words, the operations BeginTransaction, Commit and Rollback must not be performed on the same TaminoConnection or TaminoTransaction by two or more threads simultaneously.


AutoCommit

Each command runs within the scope of a single transaction. The result of each command is automatically committed by the Tamino XML Server. This means that each command affects the database immediately after it has been successfully processed.

Example

...
// open connection in AutoCommit mode
connection.Open(TaminoConnectionMode.AutoCommit);

// delete some document
TaminoResponse response = command.Delete(someDocumentUri);
Trace.Assert(response.ReturnValue == "0", response.ErrorText);
// if we get here the delete worked - oops can't undo the delete now!

// close the connection
connection.Close();
...

Top of page

LocalTransaction

The application marks the beginning and end of a transaction. All commands executed between the beginning and end of the transaction run within the scope of the transaction. To complete a transaction, the application can decide whether to commit or rollback all the changes made by all the commands. This allows the application to group a set of commands and either commit either all the changes or none of them. Using local transactions you can only group commands associated with the same Tamino database.

The following sample shows how to delete a document and then commit the delete. After being committed, the changes to the database cannot be rolled back!

Example

...
// open connection in LocalTransaction mode
connection.Open(TaminoConnectionMode.LocalTransaction);

// begin transaction
TaminoTransaction tx = connection.BeginTransaction();

// delete some document
TaminoResponse response = command.Delete(someDocumentUri);
Trace.Assert(response.ReturnValue == "0", response.ErrorText);
// if we get here the delete worked - could still undo the delete if need be

// commit the preceding commands [in this case the Delete]
tx.Commit();
// oops can't change our mind now!

// close the connection
connection.Close();
...

The following sample shows how to delete a document and then rollback the delete. This undoes the delete of the document, leaving the database in the same state as it was in before the method BeginTransaction was called (assuming that this program is the only program accessing the database).

Example

...
// open connection in LocalTransaction mode
connection.Open(TaminoConnectionMode.LocalTransaction);

// begin transaction
TaminoTransaction tx = connection.BeginTransaction();

// delete some document
TaminoResponse response = command.Delete(someDocumentUri);
Trace.Assert(response.ReturnValue == "0", response.ErrorText);
// if we get here the delete worked - could still undo the delete if need be
// we do undo the Delete by doing a Rollback

// rollback the preceding commands [in this case the Delete]
tx.Rollback();
// phew - undid the Delete!

// close the connection
connection.Close();
...

Top of page

GlobalTransaction

You can use global/distributed transactions to group commands associated with different databases. All the commands run within the scope of a distributed transaction. For a general introduction to distributed transactions in .NET, see ms-help://MS.NETFrameworkSDK/cpguidenf/html/cpconprocessingtransactions.htm.

To participate in a distributed transaction, the Tamino XML Server needs to know the transaction ID. The transaction ID of the currently-active distributed transaction can either be determined automatically by the Tamino API for .NET, or it can be explicitly specified by the application. In either case, the transaction ID is communicated to the Tamino XML Server.

If the transaction ID is to be determined automatically, then the .NET Framework property System.EnterpriseServices.ContextUtil.Transaction must specify a distributed transaction that implements the Microsoft COM+ interface ITipTransaction. This would be satisfied by a .NET application running within the MS/DTC (Microsoft's Distributed Transaction Monitor, which can coordinate commits/rollbacks in different databases) transactional environment with the application specifying that it "Requires Transaction" using the System.EnterpriseServices.TransactionAttribute. Note that the TaminoConnection.Open method must execute within the context of the distributed transaction. The TaminoConnection.Close method may not be used within an automatically-determined distributed transaction.

A TaminoConnection used in GlobalTransactionMode must not be closed if the transaction was an automatically-created transaction (as opposed to a user-created global transaction). An attempt to close such a connection would result in the Tamino server throwing an exception.

The following sample shows the code needed to use an automatically-determined transaction:

Example

...
// method/application with the .NET attribute
// [TransactionAttribute(TransactionOption.Required)]

// open connection in GlobalTransaction mode
connection.Open(TaminoConnectionMode.GlobalTransaction);

// insert a document
TaminoResponse response = command.Insert(tamDoc);
Trace.Assert(response.ReturnValue == "0", response.ErrorText);

// do NOT close the connection
...

Instead of using transactional attributes, the distributed transaction can also be explicitly under the control of the application. If it wishes to perform Tamino operations in the context of this transaction, then it must supply the transaction ID to Tamino via the TaminoConnection.Open method invocation. The TaminoConnection.Close method may be used after the distributed transaction has been terminated.

Example

...
// user starts distributed transaction in some manner

// obtain transaction id as TIP URL
TaminoTxId txId = new TaminoTxId(tipUrl);

// open the connection in GlobalTransaction mode
connection.Open(txId);

// insert a document
TaminoResponse response = command.Insert(tamDoc);
Trace.Assert(response.ReturnValue == "0", response.ErrorText);

// user terminates distributed transaction in some manner

// safe to close connection
connection.Close();
...

Top of page

Modifying Transaction Behavior

To ensure consistency, Tamino provides a sophisticated locking concept. For detailed information regarding the Tamino locking concept, please refer to the Tamino XML Server documentation. The application can specify the locking strategy to be applied for commands within transactions. The application can specify the locks at three different granularities within the API. The granularities, in order from most specific to least specific, are:

The most specific settings take precedence over the least specific settings.

Single Command

The locking strategy for the command can be specified by setting the individual TaminoCommand properties: IsolationLevel, LockMode and Lockwait. If these properties are set to anything other than their default values, then the requested lock value is applied to the next command. It also applies to subsequent commands until the lock value is reset to its default value by the application. Note that setting the IsolationLevel property per command is only allowed for connections in AutoCommit mode.

Example

...
connection.Open(TaminoConnectionMode.AutoCommit);
command.Lockwait = TaminoLockwait.No;
TaminoQueryResponse qr = command.Query(query);
command.Lockwait = TaminoLockwait.Default;
...

If no lock values are set in AutoCommit mode, then the default lock values are automatically applied by the Tamino XML Server itself.

All Transaction Commands

You can specify the locking strategy for all the commands within a specific transaction This is done by setting the lock values on the TaminoConnection.BeginTransaction invocation. This applies the same lock values to all the commands executed within the transaction.

Example

...
connection.Open(TaminoConnectionMode.LocalTransaction);
TaminoTransaction tx =
    connection.BeginTransaction(TaminoIsolationLevel.Default,
        TaminoLockMode.Protected, TaminoLockwait.Yes);
command.Query(query);
command.Delete(uri);
tx.Commit();
...

If no lock values are set in LocalTransaction mode, then the default lock values are automatically applied by the Tamino XML Server itself.

All Connection Commands

You can specify the locking strategy for all the commands for a connection. This is achieved by setting the lock values on the TaminoConnection.Open invocation. This causes all the commands executed on the connection to have the same lock values applied.

Example

...
connection.Open(TaminoConnectionMode.LocalTransaction,
    TaminoIsolationLevel.Default, TaminoLockMode.Unprotected,
        TaminoLockwait.Default);
TaminoTransaction tx = connection.BeginTransaction();
command.Query(query);
tx.Commit();
...

As noted above under the precedence rules, it is possible for a subsequent BeginTransaction invocation to provide a different set of lock values that would apply to that particular transaction.

Top of page

Transaction Timeouts

You can set the timeouts that the Tamino Server applies to transactions on a connection-by-connection basis. You specify timeout intervals by passing in an instance of TaminoPreference when creating the instance of TaminoConnection.

TaminoPreference has two fields that allow you to specify the transaction timeouts:

TransactionTimeout

Specifies the maximum time interval in seconds between Commit/Rollback calls.

NonActivityTimeout

Specifies the maximum time interval in seconds between database operations.

By default, the Tamino Server uses database-specific values. You can use the Tamino Manager to view and modify these values.

Example

...
// create suitable preferences
TaminoPreference preference = new TaminoPreference();
preference.TransactionTimeout = 60;
preference.NonActivityTimeout = 30;
 
// create connection
TaminoConnection connection = new TaminoConnection(uri, preference);
 
// open connection in LocalTransaction mode
connection.Open(TaminoConnectionMode.LocalTransaction);
 
// begin transaction
TaminoTransaction tx = connection.BeginTransaction();
 
// do commands + Rollback/Commit operations with specified timeouts applied
 
// close the connection
connection.Close();

Top of page