4D v16.3

Suspending transactions

Home

 
4D v16.3
Suspending transactions

Suspending transactions  


 

Suspending a transaction is useful when you need to perform, from within a transaction, certain operations that do not need to be executed under the control of this transaction. For example, imagine the case where a customer places an order, thus within a transaction, and also updates their address. Next the customer changes their mind and cancels the order. The transaction is cancelled, but you do not want the address change to be reverted. This is a typical example where suspending the transaction is useful. Three commands are used to suspend and resume transactions:

  • SUSPEND TRANSACTION: pauses current transaction. Any updated or added records remain locked.
  • RESUME TRANSACTION: reactivates a suspended transaction.
  • Active transaction: returns False if the transaction is suspended or if there is no current transaction, and True if it is started or resumed.

Example  

This example illustrates the need for a suspended transaction. In an Invoices database, we want to get a new invoice number during a transaction. This number is computed and stored in a [Settings] table. In a multi-user environment, concurrent accesses must be protected; however, because of the transaction, the [Settings] table could be locked by another user even though this data is independent from the main transaction. In this case, you can suspend the transaction when accessing the table.

  //Standard method that creates an invoice
 START TRANSACTION
 ...
 CREATE RECORD([Invoices])
 [Invoices]InvoiceID:=GetInvoiceNum //call the method to get an available number
 ...
 SAVE RECORD([Invoices])
 VALIDATE TRANSACTION

The GetInvoiceNum method suspends the transaction before executing. Note that this code will work even when the method is called from outside of a transaction:

  //GetInvoiceNum project method
  //GetInvoiceNum -> Next available invoice number
 C_LONGINT($0)
 SUSPEND TRANSACTION
 ALL RECORDS([Settings])
 If(Locked([Settings])) //multi-user access
    While(Locked([Settings]))
       MESSAGE("Waiting for locked Settings record")
       DELAY PROCESS(Current process;30)
       LOAD RECORD([Settings])
    End while
 End if
 [Settings]InvoiceNum:=[Settings]InvoiceNum+1
 $0:=[Settings]InvoiceNum
 SAVE RECORD([Settings])
 UNLOAD RECORD([Settings])
 RESUME TRANSACTION

When a transaction is suspended, the following principles are implemented:

  • You can access records that were added or modified during the transaction, and you cannot see any records that were deleted during the transaction.
  • You can create, save, delete, or modify records outside the transaction.
  • You can start a new transaction, but within this included transaction you will not be able to see any records or record values that were added or modified during the suspended transaction. In fact, this new transaction is totally independent from the suspended one, similar to a transaction of another process, and since the suspended transaction could later be resumed or canceled, any added or modified records are automatically hidden for the new transaction. As soon as you commit or cancel the new transaction, you can see these records again.
  • Any records that are modified, deleted or added within the suspended transaction remain locked for other processes. If you try to modify or delete these records outside the transaction or in a new transaction, an error is generated.

These implementations are summarized in the following graphic:

Values edited during transaction A (ID1 record gets Val11) are not available in a new transaction (B) created during the "suspended" period. Values edited during the "suspended" period (ID2 record gets Val22 and ID3 record gets Val33) are saved even after transaction A is cancelled. 

Specific features have been added to handle errors:

  • The current record of each table becomes temporarily locked if it is modified during the transaction and is automatically unlocked when the transaction is resumed. This mechanism is important to prevent unwanted saves on parts of the transaction.
  • If you execute an invalid sequence such as start transaction / suspend transaction / start transaction / resume transaction, an error is generated. This mechanism prevents developers from forgetting to commit or cancel any included transactions before resuming the suspended transaction.

The existing In transaction command returns True when a transaction has been started, even if it is suspended. To find out whether the current transaction is suspended, you need to use the new Transaction active command, which returns False in this case. 

Both commands, however, also return False if no transaction has been started. You may then need to use the existing Transaction level command, which returns 0 in this context (no transaction started).

The following graphic illustrates the various transaction contexts and the corresponding values returned by the transaction commands:




See also 


Active transaction
RESUME TRANSACTION
SUSPEND TRANSACTION

 
PROPERTIES 

Product: 4D
Theme: Transactions

 
HISTORY 

Created: 4D v15 R4

 
ARTICLE USAGE

4D Language Reference ( 4D v16)
4D Language Reference ( 4D v16.1)
4D Language Reference ( 4D v16.2)
4D Language Reference ( 4D v16.3)