Marks the beginning of a transaction.
Description
TSTART marks the beginning of a transaction. Following TSTART, database operations are journaled to enable a subsequent TCOMMIT or TROLLBACK command.
TSTART increments the value of the $TLEVEL special variable. A $TLEVEL value of 0 indicates that no transaction is in effect. The first TSTART begins a transaction and increments $TLEVEL to 1. Subsequent TSTART commands can create nested transactions, further incrementing $TLEVEL.
Not all operations that occur within a transaction can be rolled back. For example, setting global variables within a transaction can be rolled back; setting local variables within a transaction cannot be rolled back. Refer to Using ObjectScript for Transaction Processing in Using ObjectScript for further details.
By default, a lock issued within a transaction will be held until the end of the transaction, even if the lock is released within the transaction. This default can be overridden when setting the lock. Refer to the LOCK command for more details.
Examples
The following example uses a single-level transaction to transfer a random amount of money from one account to another. If the transfer amount is more than the available balance, the program rolls back the transaction:
SetupBankAccounts
SET num=12345
SET ^CHECKING(num,"balance")=500.99
SET ^SAVINGS(num,"balance")=100.22
IF $DATA(^NumberOfTransfers)=0 {SET ^NumberOfTransfers=0}
BankTransfer
WRITE "Before transfer:",!,"Checking=$",^CHECKING(num,"balance")," Savings=$",^SAVINGS(num,"balance"),!
// Transfer funds from one account to another
SET transfer=$RANDOM(1000)
WRITE "transfer amount $",transfer,!
DO CkToSav(num,transfer)
IF ok=1 {WRITE "sucessful transfer",!,"Number of transfers to date=",^NumberOfTransfers,!}
ELSE {WRITE "*** INSUFFICIENT FUNDS ***",!}
WRITE "After transfer:",!,"Checking=$",^CHECKING(num,"balance")," Savings=$",^SAVINGS(num,"balance"),!
RETURN
CkToSav(acct,amt)
TSTART
SET ^CHECKING(acct,"balance") = ^CHECKING(acct,"balance") - amt
SET ^SAVINGS(acct,"balance") = ^SAVINGS(acct,"balance") + amt
SET ^NumberOfTransfers=^NumberOfTransfers + 1
IF ^CHECKING(acct,"balance") > 0 {TCOMMIT SET ok=1 QUIT:ok}
ELSE {TROLLBACK SET ok=0 QUIT:ok}
The following examples use TSTART to create nested transactions. They show three scenarios for rollback of nested transactions:
Roll back the innermost transaction, commit the middle transaction, commit the outermost transaction:
KILL ^a,^b,^c
TSTART SET ^a=1 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^b=2 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^c=3 WRITE "tlevel=",$TLEVEL,!
TROLLBACK 1 WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
IF $DATA(^a) {WRITE "^a=",^a,!} ELSE {WRITE "^a is undefined",!}
IF $DATA(^b) {WRITE "^b=",^b,!} ELSE {WRITE "^b is undefined",!}
IF $DATA(^c) {WRITE "^c=",^c,!} ELSE {WRITE "^c is undefined",!}
Commit the innermost transaction, roll back the middle transaction, commit the outermost transaction:
KILL ^a,^b,^c
TSTART SET ^a=1 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^b=2 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^c=3 WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
TROLLBACK 1 WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
IF $DATA(^a) {WRITE "^a=",^a,!} ELSE {WRITE "^a is undefined",!}
IF $DATA(^b) {WRITE "^b=",^b,!} ELSE {WRITE "^b is undefined",!}
IF $DATA(^c) {WRITE "^c=",^c,!} ELSE {WRITE "^c is undefined",!}
Commit the innermost transaction, commit the middle transaction, roll back the outermost transaction:
KILL ^a,^b,^c
TSTART SET ^a=1 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^b=2 WRITE "tlevel=",$TLEVEL,!
TSTART SET ^c=3 WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
TCOMMIT WRITE "tlevel=",$TLEVEL,!
TROLLBACK 1 WRITE "tlevel=",$TLEVEL,!
IF $DATA(^a) {WRITE "^a=",^a,!} ELSE {WRITE "^a is undefined",!}
IF $DATA(^b) {WRITE "^b=",^b,!} ELSE {WRITE "^b is undefined",!}
IF $DATA(^c) {WRITE "^c=",^c,!} ELSE {WRITE "^c is undefined",!}
Note that in this third case, TROLLBACK 1 and TROLLBACK would have the same result, because both would decrement $TLEVEL to 0.