Using Read and Write Transactions
The abortTransaction and commitTransaction instructions perform the following actions.
-
Release all locks held at the time, including locks obtained in a server method that were not released after the server method execution
-
Finalize any existing load state (caused by a beginLoad instruction) or lock state (caused by a beginLock instruction)
The abortTransaction and commitTransaction instructions have priority over load state and lock state; that is, executing either instruction will release all transaction locks held by the process and finalize transaction state, load state, and lock state. For example, in the following code fragment, load state is ended by the commitTransaction instruction and the shared lock on global is released.
// Initially, we're not in load state or transaction state, and // global is not locked write "1: load state = " & process.isInLoadState.String; // false write "1: tran state = " & process.isInTransactionState.String; // false write "1: global lock = " & process.isLockedByMe(global).String; // false // Begin load state. Manual unlocks of transaction duration locks // are ignored. All transaction duration locks will be released // when we exit load state (via either endLoad, commitTransaction, // or abortTransaction). beginLoad; // Place a shared lock on global ... sharedLock(global); // ... and then unlock it. This illustrates that the manual unlock // will be ignored, as we are in load state. The write statement // below will show that global is still locked. unlock(global); write "2: load state = " & process.isInLoadState.String; // true write "2: tran state = " & process.isInTransactionState.String; // false write "2: global lock = " & process.isLockedByMe(global).String; // true // Begin a transaction. This puts us in transaction state. beginTransaction; write "3: load state = " & process.isInLoadState.String; // true write "3: tran state = " & process.isInTransactionState.String; // true write "3: global lock = " & process.isLockedByMe(global).String; // true // Commit the transaction. This ends transaction state and load // state. All transaction duration locks are released, regardless // of whether or not a manual unlock has been done. Even if the // manual unlock of global was not done above, global would still // be unlocked by the commitTransaction. An abortTransaction does // the same, except that persistent object updates are not // committed to the database. The write statement below will // show that global has been unlocked. commitTransaction; write "4: load state = " & process.isInLoadState.String; // false write "4: tran state = " & process.isInTransactionState.String; // false write "4: global lock = " & process.isLockedByMe(global).String; // false // End load state. This has already been done by the commitTransaction. // Executing an endLoad when not in load state does nothing (it does // not raise an exception). endLoad; write "5: load state = " & process.isInLoadState.String; // false write "5: tran state = " & process.isInTransactionState.String; // false write "5: global lock = " & process.isLockedByMe(global).String; // false
The abortTransaction instruction can be used, even when not in transaction state, to finalize load state and lock state and to release all transaction locks. For example:
// Initially, we're not in load state and global is not locked write "1: load state = " & process.isInLoadState.String; // false write "1: global lock = " & process.isLockedByMe(global).String; // false // Begin load state. All transaction duration locks will be // released when we exit load state (via either endLoad, // commitTransaction or abortTransaction). beginLoad; // Place a shared lock on global sharedLock(global); write "2: load state = " & process.isInLoadState.String; // true write "2: global lock = " & process.isLockedByMe(global).String; // true // Execute an abortTransaction. Even though we're not in transaction // state, this still ends load state and lock state, and releases all // transaction duration locks currently held by the process. abortTransaction; write "3: load state = " & process.isInLoadState.String; // false write "3: global lock = " & process.isLockedByMe(global).String; // false