Transaction Support

Documentation home

 

Transactions 1

Scope. 1

Transaction Timeout 2

Application controlled Commit and Rollback 2

Locking. 3

Optimistic locking. 3

Pessimistic locking. 3

 

 

Transactions

The Verj.io Server treats each interaction with the user as a discrete transaction. In detail, this means that a transaction is started each time input is received from the end user and is ended when output is sent back to the user or the form ends. It is important to realize that the scope of a transaction does not span multiple user interactions or multiple form pages. For this reason, all updates should ideally be made at the same time - typically this is done when all user input has been validated i.e. in the end of form event scripts, or a script activated as a result of an end user ‘Submit’.

 

This basic ‘single transaction’ model can be changed if required by using the FPL commit and rollback commands or API methods TransactionManager.commitAndRestartTransaction() and TransactionManager.rollbackAndRestartTransaction().

 

Please note that sequences are not included within the scope of an Verj.io transaction. Updates to sequences are made immediately when the FPL sequence command or API SequenceManager.sequence() method is invoked and cannot be rolled back.

 

Scope

Each transaction can include any or all of the following:

 

·         database updates made from Verj.io i.e. using script statements or Java classes invoked from script statements

·         all updates made by EJBs called from Verj.io (these should have transactional attribute TX_REQUIRED no enable them to join the Verj.io transaction context)

·         all updates made by custom Java functions where these are made using the standard facilities of the J2EE Application Server

·         all updates made by other application systems e.g. CICS, SAP etc. where the connection to the system is made using a resource manager managed by the J2EE Application Server

 

Verj.io uses the facilities of the J2EE Application Server to provide a transactional context. The scope of the transaction (i.e. what is included within each transaction) depends on two factors:

 

1.      The capabilities of the transaction manager - this is typically provided by the J2EE Application Server

2.      The capabilities of the resource managers used e.g. JDBC drivers, JMS providers, CICS resource managers etc.

 

The simplest form of transaction involves just one resource manager, usually a database. This type of transaction is usually easy to configure and in most cases is the default behaviour for the application server and the resource manager being used. In this scenario, all updates to the resource made from Verj.io plus updates made from Java classes or EJBs called via Verj.io custom functions and custom resources will be included in the transaction.

 

Transactions that span more than one resource manager are more complex e.g. two database providers or one database and a JMS provider. These require two things : a two phase commit transaction manager, and resource managers that understand the two phase commit protocol. This type of behaviour is more complex and application servers and resource managers vary in their ability to support it. You will need to read the documentation provided by your application server and the resource managers to see whether they provide this support and how it is configured.

 

To access the transactional facilities of the J2EE Application Server, Verj.io performs a lookup in the application server's naming service using the name "java:comp/UserTransaction". However, some application servers use a different name and this can be specified in the Ufs.transactionJNDIName property of the server properties file UfsSetup.properties.

 

Transaction Timeout

The transaction timeout period can be specified:

 

·         With server property Transaction Timeout. If specified this overrides the previous property. This property has the advantage that it can be changed without restarting the server.

·         Can be overridden using Javascript:

system.transactionManager.setDefaultTransactionTimeout();

system.transactionManager.commitAndRestartTransaction();

 

The default value for your system should be large enough to accommodate the longest running transaction that occurs in normal processing. In particular, it may be necessary to specify a higher value if long running scheduled tasks are used. If you have failures which include message Transaction was marked for rollback and has been rolled back, this indicates that the transaction period has been exceeded.

 

 

Application controlled Commit and Rollback

Each transaction is committed automatically by the system each time a page is sent to the end user or when the form ends normally. If an error occurs during form execution that results in abnormal termination of the form, the transaction will be automatically rolled back.

 

In addition, the FPL commit and rollback script commands (Javascript methods TransactionManager.commitAndRestartTransaction() and TransactionManager.rollbackAndRestartTransaction() ) are provided to enable the designer to commit or rollback a transaction as required by the application. These commands/methods will then start an additional transaction to handle any further processing. This makes it possible for an application to create many transactions that are committed or rolled back under application control.

 

Commit and rollback can also be called by customer written Java code extensions – custom functions and custom resources. Both of these extensions can call commitTransaction() and rollbackTransaction() on their respective interfaces UFSFormInterface and ResourceRequestInterface. In both cases, the system will automatically start an additional transaction to handle any further processing. See javadoc for futher details

 

Please note that updates to sequences are not affected by these commands. These updates are made immediately when the FPL sequence command or API SequenceManager.sequence() method is issued, and cannot be rolled back or explicitly committed.

 

Locking

The transaction support described in the previous section provides a transactional context covering only a single interaction with the end user. Therefore, this cannot be used to lock database (or other) resources across an entire form consisting of multiple pages. To meet these requirements Verj.io provides explicit locking support covering both optimistic and pessimistic locking.

 

Optimistic locking

This option is activated by selecting the optimistic locking option on the Transactions tab of Form properties for the form. It applies only to database updates of a single record.

 

When the option is selected, the system will check that a record about to be updated has the same values as it did when it was originally read from the database using an FPL fetch command or API DatabaseResource.fetch() method. If the values are unchanged then the update is performed. If the values have been changed, the update is not performed:

 

·         With the FPL language, the command status is set indicating the error (see update command in FPL Script Command Syntax) and this must be checked by the script issuing the update; this script should then take appropriate steps e.g. inform the end user.

 

·         With an API based language, the DatabaseResource.update() method throws an OptimisticLockingException

 

Note: optimistic locking is not available for table operations where the table is backed by a database resource i.e. it is not support for fetchtable and updatetable commands or API Table.fetchTable() or Table.updateTable() methods,.

                                                                                                                                                    

Pessimistic locking

Verj.io provides the ability to acquire and release locks against an abstract resource. This is designed for use by more advanced applications where the resource to be locked is more complex than a simple database table. The locks are acquired and released using the FPL script commands lock and unlock or API methods LockManager.lock() and LockManager.unlock(). These commands both require a resource name and a resource id. The resource name can be any name but it is obviously important that the same name is used by all forms that access the same resource. Examples of resource names might be CUSTOMER, CONTRACT, ORDER etc. The resource id is a unique identifier to identify this particular resource e.g. customer number, contract number etc.

 

With the FPL language, if a lock command is issued and the requested lock is held by another user, the command status will be set to 'ERROR'. The FPL script issuing the lock must check the command status and take appropriate action if the lock could not be acquired.

 

The following example shows FPL commands to acquire a lock for a customer modification form:

 

lock 'CUSTOMER', CUSTOMER_ID;             (where CUSTOMER_ID is a form field containing a unique customer identifier)

if [ $COMMAND_STATUS = 'ERROR' ]

message E,1234, CUSTOMER_ID;

endif

 

Message 1234 is: "Customer && is currently being modified by another user - please try again later."

 

The FPL script command to release the lock is:

 

unlock 'CUSTOMER', CUSTOMER_ID;                                                                                                                                                                                                                   

 

With an API based language, LockManager.lock() returns false if the requested lock is held by another user.

 

All locks are exclusive i.e. they can only be held by one user at a time. Verj.io does not support shared locks.

 

The scope of a lock includes an entire form i.e. it spans multiple user interactions. All held locks are released by the system automatically when the form ends, either normally or abnormally. However, it is good practice to explicitly release locks when they are no longer required.

 

The locks held can be displayed using the Server Administration Application