Providing support for transactions
Benefits of EAServer’s transaction
support
EAServer components that
you develop in PowerBuilder can participate in EAServer transactions. An EAServer
transaction is a transaction whose boundaries and outcome
are determined by EAServer. You
can mark components to indicate that they will provide transaction
support. When a component provides transaction support, EAServer ensures that the component’s
database operations execute as part of a transaction.
Multiple EAServer components
can participate in a single EAServer transaction; EAServer ensures that database changes
performed by the participating components are all committed or rolled
back. By defining components to use EAServer transactions,
you can ensure that all work performed by components that participate
in a transaction occurs as intended.
Indicating how the component will support transactions
Each EAServer component
has a transaction attribute that indicates how the component participates
in EAServer transactions. When
you develop an EAServer component
in PowerBuilder, you can specify the transaction attribute in the
wizards. Table 23-4 lists
the options.
Transaction type |
Description |
---|---|
Not supported |
The component never executes as part |
Supports Transaction |
The component can execute in the context |
Requires Transaction |
The component always executes in a transaction. |
Requires New Transaction |
Whenever the component is instantiated, |
Mandatory |
Methods can be invoked only by a client |
OTS Style |
The component can manage transactions. |
Never |
Methods cannot be invoked when there |
Using the transaction service context object
Component methods can call EAServer’s transaction
state primitives to influence whether EAServer commits
or aborts the current transaction. To give you access to EAServer’s transaction
state primitives, PowerBuilder provides a transaction service context
object called TransactionServer.
If you plan to
use the TransactionServer context object, you should set the UseContextObject
DBParm parameter to Yes.
For transactional components, setting UseContextObject to
Yes tells PowerBuilder that you will be using the methods of the
TransactionServer object rather than COMMIT and ROLLBACK to
indicate whether the component has completed its work for the current
transaction. If your scripts contain COMMIT and ROLLBACK statements,
they will generate a runtime error. Setting UseContextObject to
No causes COMMIT and ROLLBACK statements
to call the EAServer transaction service’s CommitWork and AbortWork methods.
You should only use this setting if you want to retain legacy code
and you do not want to use the TransactionServer object.
For components that do not need to be in a transaction, the
UseContextObject setting is ignored and PowerBuilder drivers handle COMMIT and ROLLBACK statements.
To use the transaction context service, declare a variable
of type TransactionServer and call the GetContextService function
to create an instance of the service.
Example
In the Activate (or Constructor) event for a component, you
can call GetContextService to instantiate the
TransactionServer service:
1 |
// Instance variable:<br>// TransactionServer ts<br> <br>Integer li_rc<br>li_rc = this.GetContextService("TransactionServer", &<br>   ts)<br>IF li_rc <> 1 THEN<br>   // handle the error<br>END IF |
In one of the component methods, you can then update the database
and call SetComplete if the update succeeds or SetAbort if
it fails:
1 |
//Instance variable:<br>//DataStore ids_datastore<br>long ll_rv<br>...<br>...<br>ll_rv = ids_datastore.Update()<br>IF ll_rv = 1 THEN<br>   ts.SetComplete()<br>ELSE<br>   ts.SetAbort()<br>END IF |
The TransactionServer interface provides the methods in Table 23-5 to allow you to
access EAServer’s transaction
primitives.
Method |
Description |
---|---|
DisableCommit |
Indicates that the current transaction |
EnableCommit |
Indicates that the component should not |
IsInTransaction |
Determines whether the current method |
IsTransactionAborted |
Determines whether the current transaction |
SetAbort |
Indicates that the component cannot complete |
SetComplete |
Indicates that the component has completed |
Automatic Demarcation/ Deactivation
If you want a component to be automatically deactivated after
each method invocation, you can enable Automatic Demarcation/Deactivation
for the component. This sets the component’s tx_vote
property to FALSE. When Automatic Demarcation/Deactivation
is enabled, you do not need to make explicit calls to SetComplete to
cause deactivation because SetComplete is assumed
by default. To roll back the transaction, you can call SetAbort.
If you do not want the component to be automatically deactivated
after each method invocation, disable the Automatic Demarcation/Deactivation
setting for the component. This sets the component’s tx_vote
property to TRUE. When you disable Automatic
Demarcation/Deactivation, EAServer waits
for notification before completing transactions; therefore, be sure
to deactivate programmatically by making an explicit call to SetComplete (or SetAbort).
COMMIT and ROLLBACK
You have the option to disable the TransactionServer context
object and use the COMMIT and ROLLBACK statements
instead to specify the EAServer transaction
state for a component. This capability is provided to allow you
to migrate PowerBuilder 6 objects to EAServer without
modifying the code. To disable the TransactionServer context object,
set the UseContextObject DBParm parameter
to No. When you do this, COMMIT is equivalent
to SetComplete and ROLLBACK is
equivalent to SetAbort.
In nontransactional components that disable the TransactionServer
context object, COMMIT does not invoke SetComplete and ROLLBACK does
not invoke SetAbort. For example, if you specify
Not Supported as the transaction type, disable Automatic Demarcation/Deactivation
(set tx_vote to TRUE), and set the UseContextObject
parameter to No, the PowerBuilder virtual machine does not issue
a SetComplete when you execute a COMMIT (or
a SetAbort when you execute a ROLLBACK).
In this case, EAServer never releases
the component because it is waiting for a call to SetComplete or SetAbort.
If you disable Automatic Demarcation/Deactivation
for a component that performs no database access whatsoever, then
you must use the TransactionServer object to call SetComplete (or SetAbort)
to deactivate the component. Otherwise, the component will never
be deactivated.
Transaction handling and runtime errors
You can control the behavior of EAServer when
an internal exception occurs in the PBVM or a PowerBuilder component
raises a runtime exception. To do so, set the PBOnFatalError or
PBRollbackOnRTError environment variables in a batch file or as
a system environment variable on the server on which the component
runs.
Variable |
Description |
---|---|
PBOnFatalError |
Specifies whether EAServer should Values are:
|
PBRollbackOnRTError |
Specifies how a transaction is handled Values are:
|
Transactions and the component lifecycle
EAServer’s transaction
model and the component lifecycle are tightly integrated. Component
instances that participate in a transaction are never deactivated
until the transaction ends or until the component indicates that
its contribution to the transaction is over (its work is done and
ready for commit or its work must be rolled back). An instance’s
time in the active state corresponds exactly to the beginning and
end of its participation in a transaction.
For more information, see the EAServer documentation.