Skip to main content

TROLLBACK (ObjectScript)

Rolls back an unsuccessful transaction.



TRO:pc 1


Argument Description
pc Optional — A postconditional expression.
1 Optional — The integer 1. Rolls back one level of nesting. Must be specified as a literal.


TROLLBACK terminates the current transaction and restores all journaled database values to the values they held at the start of the transaction. TROLLBACK has two forms:

  • TROLLBACK rolls back all transactions in progress (no matter how many levels of TSTART were issued) and resets $TLEVEL to 0.

  • TROLLBACK 1 rolls back the current level of nested transactions (the one initiated by the most recent TSTART) and decrements $TLEVEL by 1. The 1 argument must be the literal number 1; it cannot be a variable or an expression that resolve to 1. Numbers other than 1 are not supported.

You can determine the level of nested transactions from the $TLEVEL special variable. Calling TROLLBACK when $TLEVEL is 0 has no effect.

You can use the GetImageJournalInfo() method of the %SYS.Journal.System class to search the journal file for TSTART commands, and thus identify open transactions. A TSTART increments $TLEVEL and writes a journal file record: either a “BT” (Begin Transaction) record if $TLEVEL was zero, or a “BTL” (Begin Transaction with Level) record if $TLEVEL was greater than 0. Use the Sync() method of the %SYS.Journal.System class to flush the journal buffer following a successful rollback operation.

TROLLBACK disables Ctrl-C interrupts for the duration of the rollback operation.

What Is and Isn’t Rolled Back

TROLLBACK rolls back all journaled operations. These include the following:

  • TROLLBACK rolls back most changes to global variables, including SET and KILL operations. Global variables underlie many InterSystems IRIS operations. Local variables are not reverted by a rollback operation.

    TROLLBACK rolls back changes to bit string values in global variables during a transaction. However, a rollback operation does not return the global variable bit string to its previous internal string representation.

  • TROLLBACK rolls back insert, update, and delete changes to SQL data.

However, not all changes made by an application are journaled:

  • TROLLBACK does not roll back changes to local variables or process-private globals.

  • TROLLBACK does not roll back changes to special variables, such as $TEST.

  • TROLLBACK does not roll back changes to the current namespace.

  • TROLLBACK does not roll back LOCK command lock or unlock operations.

  • TROLLBACK does not roll back $INCREMENT changes to global variables.

  • TROLLBACK does not roll back $SEQUENCE changes to global variables.

InterSystems IRIS treats a SET or KILL of a global variable as a journaled transaction event; rolling back the transaction reverses these operations. InterSystems IRIS does not treat a SET or KILL of a local variable or a process-private global variable as a journaled transaction event; rolling back the transaction has no effect on these operations. By default, a SET or KILL of a global variable is immediately visible by other processes while the transaction is in progress. To prevent the SET or KILL of a global variable invoked within a transaction from being seen by other users before the transaction has been committed, you must coordinate access to the global variable via the LOCK command.

Transaction Rollback Logging

If an error occurs during a roll back operation, InterSystems IRIS issues a <ROLLFAIL> error message, and logs an error message in the messages.log operator messages log file. You can use the Management Portal System Operation option to view messages.log: System Operation, System Logs, Messages Log.

By default, the messages.log operator messages log file is in the InterSystems IRIS system management directory (mgr). This default location is configurable. Go to the Management Portal System Administration option, select Configuration, then Additional Settings, then Advanced Memory. View and edit the current setting of ConsoleFile. By default this setting is blank, routing console messages to messages.log in the mgr directory. You can specify a different directory location for the messages.log file.


If TROLLBACK cannot successfully roll back the transaction, a <ROLLFAIL> error occurs. The process behavior depends on the setting of the system-wide journal configuration setting flag Freeze on error (from Management Portal select System Administration, Configuration, System Configuration, Journal Settings):

  • If Freeze on error is not set (the default), the process gets a <ROLLFAIL> error. The transaction is closed and any locks retained for the transaction are released. This option trades data integrity for system availability.

  • If Freeze on error is set, the process halts and the clean job daemon (CLNDMN) retries rolling back the open transaction. During the CLNDMN retry period, locks retained for the transaction are intact and, as a result, the system might hang. This option trades system availability for data integrity.

For further details, refer to Journal IO Errors in the Data Integrity Guide.

When a <ROLLFAIL> occurs, the %msg records both the <ROLLFAIL> error itself, and the previous error that caused the roll back. For example, attempting to update a date with an out-of-range value and then failing roll back might return the following %msg: SQLCODE = -105 %msg = Unexpected error occurred: <ROLLFAIL>%0Ac+1^dpv during TROLLBACK. Previous error: SQLCODE=-105, %msg='Field 'Sample.Person.DOB' (value '5888326') failed validation'.

A <ROLLFAIL> occurs upon transaction rollback if within the transaction a global accessed a remote database, and then the program explicitly dismounted that remote database.

A <ROLLFAIL> occurs upon transaction rollback if the process disabled journaling before making database changes and an error occurred that invoked transaction rollback. A <ROLLFAIL> does not occur upon transaction rollback if the process disabled journaling after all database changes had been made but before issuing the TROLLBACK command. Instead, InterSystems IRIS temporarily enables journaling for the duration of the rollback operation. Upon completion of the rollback operation InterSystems IRIS again disables journaling.

Transactions Suspended

The TransactionsSuspended() method of the %SYSTEM.Process class can be used to suspend and resume all current transactions system-wide. Suspending transactions suspends journaling of changes. Therefore, if transaction suspension occurred during the current transaction, TROLLBACK cannot roll back any changes made while transactions were suspended; however, TROLLBACK rolls back any changes made during the current transaction that occurred before or after the tranaction suspension was in effect.

For further details, refer to Using ObjectScript for Transaction Processing in Using ObjectScript.

SQL and Transactions

ObjectScript and SQL transaction commands are fully compatible and interchangeable, with the following exception:

ObjectScript TSTART and SQL START TRANSACTION both start a transaction if no transaction is current. However, START TRANSACTION does not support nested transactions. Therefore, if you need (or may need) nested transactions, it is preferable to start the transaction with TSTART. If you need compatibility with the SQL standard, use START TRANSACTION.

ObjectScript transaction processing provides limited support for nested transactions. SQL transaction processing supplies support for savepoints within transactions.

Purging Cached Queries

If during a transaction you call the Purge() method of %SYSTEM.SQL class to purge cached queries, the cached queries are permanently deleted. A subsequent TROLLBACK will not restore purged cached queries.

Globals and TROLLBACK 1

TROLLBACK 1 rolls back and restores all globals changed within its nested transaction. However, if globals are changed that are mapped to a remote system that does not support nested transactions, these changes are treated as occurring at the outermost nested level. Such globals are only rolled back when a rollback resets $TLEVEL to 0, either by calling TROLLBACK or by calling TROLLBACK 1 when $TLEVEL=1.

Locks and TROLLBACK 1

TROLLBACK 1 does not restore locks established during its nested transaction to their prior state. All locks established during a transaction remain in the lock table until the transaction is concluded by a TROLLBACK to level 0 or a TCOMMIT. At that point InterSystems IRIS releases all locks created during the nested transaction, and restores all preexisting locks to their state before TSTART.

A TCOMMIT of a nested transaction does not release the corresponding locks, so a subsequent TROLLBACK can effect locks in a committed sub-transaction.



An optional postconditional expression. InterSystems IRIS executes the command if the postconditional expression is true (evaluates to a nonzero numeric value). InterSystems IRIS does not execute the command if the postconditional expression is false (evaluates to zero). For further details, refer to Command Postconditional Expressions in Using ObjectScript.


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 uses TROLLBACK to roll back the transaction:

   SET num=12345
   SET ^CHECKING(num,"balance")=500.99
   SET ^SAVINGS(num,"balance")=100.22
   IF $DATA(^NumberOfTransfers)=0 {SET ^NumberOfTransfers=0}
   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,!}
   WRITE "After transfer:",!,"Checking=$",^CHECKING(num,"balance")," Savings=$",^SAVINGS(num,"balance"),!
  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}

The following example shows the effects of TROLLBACK on nested transactions. Each TSTART increments $TLEVEL and sets a global. Issuing a TCOMMIT on the inner nested transaction decrements $TLEVEL, but the commitment of changes made in a nested transaction is deferred. In this case, the subsequent TROLLBACK on the outer transaction rolls back all changes made, including those in the inner “committed” nested transaction.

  SET ^a(1)="[- - -]",^b(1)="[- - -]"
  WRITE !,"level:",$TLEVEL," ",^a(1)," ",^b(1)
   LOCK +^a(1)
   SET ^a(1)="hello"
   WRITE !,"level:",$TLEVEL," ",^a(1)," ",^b(1)
     LOCK +^b(1)
     SET ^b(1)="world"
     WRITE !,"level:",$TLEVEL," ",^a(1)," ",^b(1)
  WRITE !,"level:",$TLEVEL," ",^a(1)," ",^b(1)
  WRITE !,"level:",$TLEVEL," ",^a(1)," ",^b(1)

The following example shows how TROLLBACK rolls back global variables, but not local variables:

  SET x="default",^y="default"
  WRITE !,"level:",$TLEVEL
  WRITE !,"local:",x," global:",^y
  SET x="first",^y="first"
  WRITE !,"local:",x," global:",^y
    SET x=x_" second",^y=^y_" second"
    WRITE !,"TSTART level:",$TLEVEL
    WRITE !,"local:",x," global:",^y
     SET x=x_" third",^y=^y_" third"
    WRITE !,"TSTART level:",$TLEVEL
    WRITE !,"local:",x," global:",^y
  WRITE !!,"After Rollback:"
  WRITE !,"local:",x," global:",^y

The following example shows how $INCREMENT changes to a global are not rolled back.

  SET ^x=-1,^y=0
  WRITE !,"level:",$TLEVEL
  WRITE !,"Increment:",$INCREMENT(^x)," Add:",^y
  SET ^y=^y+1
  WRITE !,"level:",$TLEVEL
  WRITE !,"Increment:",$INCREMENT(^x)," Add:",^y
    SET ^y=^y+1,^z=^z_" second"
    WRITE !,"level:",$TLEVEL
    WRITE !,"Increment:",$INCREMENT(^x)," Add:",^y
     SET ^y=^y+1,^z=^z_" third"
     WRITE !,"level:",$TLEVEL
     WRITE !,"Increment:",$INCREMENT(^x)," Add:",^y
  WRITE !!,"After Rollback"
  WRITE !,"level:",$TLEVEL
  WRITE !,"Increment:",^x," Add:",^y

See Also