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()Opens in a new tab method of the %SYS.Journal.SystemOpens in a new tab 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()Opens in a new tab method of the %SYS.Journal.SystemOpens in a new tab 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. Consequently it has the following effects on changes made within transactions:

  • TROLLBACK rolls back most changes to global variables, including SET and KILL operations; the exceptions are in the next list.


    By default, a SET or KILL of a global variable is immediately visible by other processes, which may be running outside of the transaction. To prevent the SET or KILL of a global variable from being seen by other processes, you must coordinate access to the global variable via the LOCK command.

  • 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, and consequently TROLLBACK does not roll back the following changes, even when they are performed within transactions:

  • Changes to local variables or process-private globals

  • Changes to special variables, such as $TEST

  • Changes to the current namespace

  • LOCK command lock or unlock operations

  • $INCREMENT changes to global variables

  • $SEQUENCE changes to global variables

  • Changes made externally to the database

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.

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()Opens in a new tab method of the %SYSTEM.ProcessOpens in a new tab class can be used to suspend and resume all current transactions for a process. 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 transaction suspension was in effect.

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

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()Opens in a new tab method of %SYSTEM.SQLOpens in a new tab 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.


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

FeedbackOpens in a new tab