Defining a Transaction

In this section:

You define a logical transaction by issuing a COMMIT or ROLLBACK command following the transaction's last data source command. (For simplicity, the remainder of this topic refers to COMMIT only, but unless stated otherwise, both commands are meant.) For example, the beginning of your application is the beginning of its first logical transaction. The data source commands that follow are part of the transaction. When the application issues its first COMMIT command, it marks the end of the first transaction.

The data source commands that follow the first COMMIT become part of the second logical transaction; the next COMMIT to be issued marks the end of the second transaction, and so on.

The COMMIT command defines the transaction's boundary. All data source commands issued between two COMMIT commands are in the same transaction. (This explanation describes the simplest case, in which a transaction exists entirely within a single procedure. When a transaction spans procedures, you have several options for deciding how to define a transaction's boundary, as described in When an Application Ends With an Open Transaction.)


Top of page

Example: Defining a Simple Transfer of Funds Transaction

For example, transferring money from a savings account to a checking account requires two update commands. If you want to define the transfer, including both updates, as one logical transaction, you could use the following function:

CASE TransferMoney
   UPDATE Savings FROM SourceAccts
   UPDATE Checking FROM TargetAccts
   COMMIT
ENDCASE

Top of page

x
When Does a Data Source Command Cause a Transaction to Fail?

A data source command can fail for many reasons. For example, an UDPATE command might try to write to a record that never existed because a key was mistyped, or an INCLUDE command might try to add a record that has already been added by another user.

In some cases, when a command fails, you might want to keep the transaction open and simply resolve the problem that caused the command to fail. For example, in the first case of attempting to update a record that does not exist, you might wish to ask the application end user to correctly re-enter the customer code (which is being used as the key of the record). In other cases, you might wish to roll back the entire transaction.

If a data source command fails, it will only cause the logical transaction that contains it to be automatically rolled back in certain circumstances. The deciding factor is when a data source command fails. If a data source command fails when the transaction:


Top of page

x
Canceling a Transaction

A transaction that is ongoing and has not yet been committed is called an open transaction. To cancel an open transaction, you must issue a ROLLBACK command. ROLLBACK voids any of the data source commands of the transaction that have already been issued so that none of them are written to the data source.


Top of page

x
Transactions and Data Source Position

When a logical transaction is committed or rolled back, it resets all position markers in all the data sources that are accessed by the transaction's procedures. (Resetting a data source's position markers points them to the beginning of the data source's segment chains.)


Top of page

x
How Large Should a Transaction Be?

A transaction is at its optimal size when it includes only those data source commands that are mutually dependent upon each other for validity. If you include "independent" commands in the transaction and one of the independent commands fails when you try to commit the transaction, the dependent group of commands will be needlessly rolled back.

For example, in the following banking transaction that transfers funds from a savings account to a checking account

CASE TransferMoney
UPDATE Savings FROM SourceAccts
UPDATE Checking FROM TargetAccts
COMMIT
ENDCASE

you should not add an INCLUDE command to create a new account, since the validity of transferring money from one account to another does not depend upon creating a new account.

Another reason for not extending transactions unnecessarily is that, in a multi-user environment, the longer a transaction takes, the more likely it is to compete for records with transactions submitted by other users. Transaction processing in a multi-user environment is described in Concurrent Transaction Processing.


Top of page

x
Designing Transactions That Span Procedures

Logical transactions can span multiple Maintain procedures. If a Maintain procedure with an open transaction passes control to a WebFOCUS procedure, the open transaction is suspended; when control next passes to a Maintain procedure, the transaction picks up from where it had left off.

When a transaction spans several procedures, you will usually find it easier to define the boundaries of the transaction if you commit it in the highest procedure in the transaction (that is, in the procedure closest to the root procedure). Committing a transaction in a descendant procedure of a complex application, where it is more difficult to track the flow of execution, makes it difficult to determine the transaction's boundaries (that is, to know which data source commands are being included in the transaction).

When a child procedure returns control to its parent procedure, and the child has an open logical transaction, you have two options:

KEEP and RESET are described in the Maintain Getting Started and Maintain Language Reference manuals.



Example: Moving a Transaction Boundary Using GOTO END KEEP

Consider a situation where procedure A calls procedure B, and procedure B then calls procedure C. The entire application contains no COMMIT commands, so the initial logical transaction continues from the root procedure (A) through the descendant procedures (B and C). C and B both return control to their parent procedure using a GOTO END command.

The table below shows how specifying or omitting the KEEP option when procedures B and C return control affects the transaction boundaries of the application, that is, how the choice between KEEP and the implied COMMIT determines where the initial transaction ends, and how many transactions follow.

C returns to B with...

B returns to A with...

Transaction boundaries (||)

KEEP

KEEP

A-B-C-B-A one transaction

KEEP

implied COMMIT

A-B-C-B || A two transactions

implied COMMIT

KEEP

A-B-C || B-A two transactions

implied COMMIT

implied COMMIT

A-B-C || B || A three transactions



x
Designing Transactions That Span Data Source Types

If a transaction writes to multiple types of data sources, each database management system (DBMS) evaluates its part of the transaction independently. When a COMMIT command ends the transaction, the success of the COMMIT against each data source type is independent of the success of the COMMIT against the other data source types. This is known as a broadcast commit. If any part of the broadcast commit fails, the value of FocCurrent is not zero.

For example, if you issue a Maintain procedure against the FOCUS data sources Employee and JobFile and a DB2 data source named Salary, the success or failure of the COMMIT against Salary is independent of its success against Employee and JobFile. It is possible for it to be successful against Salary and write that part of the transaction, while being unsuccessful against Employee and JobFile and roll back that part of the transaction. Because it is unsuccessful against Employee and JobFile, the value of FocCurrent is not zero.


Top of page

x
Designing Transactions in Multi-Server Applications

In an application that spans multiple WebFOCUS Servers, the server defines the maximum scope of a logical transaction. No transaction boundary can extend beyond a WebFOCUS Server. If one of your applications spans several servers, protect its transaction boundaries by ensuring that:

If a procedure with an open transaction calls another procedure that resides on a different WebFOCUS Server, and the situation violates either of the previous restrictions, the data source commands on the new server will comprise a new transaction. When control returns to the calling procedure on the original server, the original open transaction continues from where it had left off.


Top of page

x
When an Application Ends With an Open Transaction

If an application terminates while a logical transaction is still open, Maintain issues an implied COMMIT command to close the open transaction, ensuring that any data source commands issued after the last explicit COMMIT are accounted for. The only exception is if your WebFOCUS Maintain session abnormally terminates: Maintain does not issue the implied COMMIT, and any remaining uncommitted data source commands are rolled back.


WebFOCUS