Skip to main content
Previous sectionNext section

Transactions and Locking

The Native API for .NET offers an alternative to the standard ADO.NET/SQL transaction model, based on ObjectScript transaction and locking methods. For information on the ObjectScript transaction model, see “Transaction Processing” in Using ObjectScript.

The following topics are discussed in this chapter:

Important:
Never Mix IRIS Native and ADO.NET Transaction Models

DO NOT mix the IRIS Native transaction model with the ADO.NET/SQL transaction model.

  • If you want to use only IRIS Native commands within a transaction, you should always use IRIS Native transaction methods.

  • If you want to use a mix of IRIS Native and ADO.NET/SQL commands within a transaction, you should turn autoCommit OFF and then always use IRIS Native transaction methods.

  • If you want to use only ADO.NET/SQL commands within a transaction, you can either always use SQL transaction methods, or turn autocommit OFF and then always use IRIS Native transaction methods.

  • Although you can use both models in the same application, you must take care never to start a transaction in one model while a transaction is still running in the other model.

Controlling Transactions

The methods described here are alternatives to the standard ADO.NET/SQL transaction model. The Native API model for transaction and concurrency control is based on ObjectScript methods, and is not interchangeable with the .NET model. The Native API model must be used if your transactions include Native API method calls.

For more information on the ObjectScript transaction model, see “Transaction Processing” in Using ObjectScript.

The Native API provides the following methods to control transactions:

  • IRIS.TCommit() — commits one level of transaction.

  • IRIS.TStart() — starts a transaction (which may be a nested transaction).

  • IRIS.GetTLevel() — returns an int value indicating the current transaction level (0 if not in a transaction).

  • IRIS.TRollback() — rolls back all open transactions in the session.

  • IRIS.TRollbackOne() — rolls back the current level transaction only. If this is a nested transaction, any higher-level transactions will not be rolled back.

The following example starts three levels of nested transaction, setting the value of a different node in each transaction level. All three nodes are printed to prove that they have values. The example then rolls back the second and third levels and commits the first level. All three nodes are printed again to prove that only the first node still has a value.

Controlling Transactions: Using three levels of nested transaction
  String globalName = "myGlobal";
  iris.TStart();

  // GetTLevel() is 1: create myGlobal(1) = "firstValue"
  iris.Set("firstValue", globalName, iris.GetTLevel());

  iris.TStart();
  // GetTLevel() is 2: create myGlobal(2) = "secondValue"
  iris.Set("secondValue", globalName, iris.GetTLevel());

  iris.TStart();
  // GetTLevel() is 3: create myGlobal(3) = "thirdValue"
  iris.Set("thirdValue", globalName, iris.GetTLevel());

  Console.WriteLine("Node values before rollback and commit:");
  for (int ii=1;ii<4;ii++) {
    Console.Write(globalName + "(" + ii + ") = ");
    if (iris.isDefined(globalName,ii) > 1) Console.WriteLine(iris.GetString(globalName,ii));
    else Console.WriteLine("<valueless>");
  }
// prints: Node values before rollback and commit:
//         myGlobal(1) = firstValue
//         myGlobal(2) = secondValue
//         myGlobal(3) = thirdValue

  iris.TRollbackOne();
  iris.TRollbackOne();  // roll back 2 levels to GetTLevel 1
  iris.TCommit();  // GetTLevel() after commit will be 0
  Console.WriteLine("Node values after the transaction is committed:");
  for (int ii=1;ii<4;ii++) {
    System.out.print(globalName + "(" + ii + ") = ");
    if (iris.isDefined(globalName,ii) > 1) Console.WriteLine(iris.GetString(globalName,ii));
    else Console.WriteLine("<valueless>");
  }
// prints: Node values after the transaction is committed:
//         myGlobal(1) = firstValue
//         myGlobal(2) = <valueless>
//         myGlobal(3) = <valueless>
Copy code to clipboard

Concurrency Control

Concurrency control is a vital feature of multi-process systems such as InterSystems IRIS. It provides the ability to lock specific elements of data, preventing the corruption that would result from different processes changing the same element at the same time. The Native API transaction model provides a set of locking methods that correspond to ObjectScript commands. These methods must not be used with the ADO.NET/SQL transaction model (see the warning at the beginning of this chapter for details).

The following methods of class IRIS are used to acquire and release locks. Both methods take a lockMode argument to specify whether the lock is shared or exclusive:

   Lock(string lockMode, int timeout, string globalName, Object[] subscripts)
   Unlock(string lockMode, string globalName, Object[] subscripts)
Copy code to clipboard
  • IRIS.Lock() — Takes lockMode, timeout, globalName, and subscripts arguments, and locks the node. The lockMode argument specifies whether any previously held locks should be released. This method will time out after a predefined interval if the lock cannot be acquired.

  • IRIS.Unlock() — Takes lockMode, globalName, and subscripts arguments, and releases the lock on a node.

The following argument values can be used:

  • lockMode — combination of the following chars, S for shared lock, E for escalating lock, default is empty string (exclusive and non-escalating)

  • timeout — amount to wait to acquire the lock in seconds

Note:

You can use the Management Portal to examine locks. Go to System Operation > Locks to see a list of the locked items on your system.

There are two ways to release all currently held locks:

  • IRIS.ReleaseAllLocks() — releases all locks currently held by this connection.

  • When the Close() method of the connection object is called, it releases all locks and other connection resources.

Tip:

A detailed discussion of concurrency control is beyond the scope of this book. See the following books and articles for more information on this subject: