Client- and component-demarcated transactions
Client applications and EAServer components
marked as OTS style or Bean Managed can create, control, and obtain
information about EAServer transactions
using functions of the CORBACurrent context service object. The CORBACurrent
object provides most of the methods defined for the CORBA Current
interface.
Two-phase commit
Components in a client- or component-demarcated transaction
must be running on a server that is using the OTS/XA transaction
coordinator. This transaction coordinator supports the two-phase
commit protocol, which uses detailed records from all participants
to protect against system failures. In the prepare phase, the transaction
coordinator obtains a guarantee from every participant in the transaction
that it can be committed and writes a prepare record to the log. In
the commit phase, the coordinator notifies all participants, resources
are released, the transaction is committed, and a commit record
is written to the log.
Components using two-phase commit must connect to a database
using a PowerBuilder database interface that is XA-compliant.
An OTS/XA transaction coordinator uses XA resources
instead of connection caches to manage transactions. For more information
about creating and managing XA resources, see the EAServer documentation.
Creating components that can manage transactions
To create an EAServer component
that can manage transactions, check the OTS Style box in the EAServer Project wizard or the Project
painter. You can also select OTS Style on the Transaction tab of
the property sheet for the component in EAServer Manager
or Bean Managed in the Management Console after you have deployed
the component.
Initializing the CORBACurrent object
Before you can invoke the functions of the CORBACurrent context
service object, you need to create an instance of the object using
the GetContextService function, and then initialize
it using the Init function.
For transactions managed by a component, call the Init function
with no arguments:
1 |
GetContextService("CORBACurrent", myCorbCurr)<br>myCorbCurr.Init() |
For client-demarcated transactions, you must call the Init function
with an argument: either an instance of the Connection object with
which you have already established a connection, or a URL that identifies
a valid EAServer host.
Because the Connection object is more portable, using it is
the preferred technique.
1 |
myCorbCurr.Init( myconnect )<br>// OR<br>myCorbCurr.Init( "iiop://localhost:2000") |
Beginning and ending transactions
You begin a client- or component-demarcated transaction by
calling the BeginTransaction function and end
it by calling CommitTransaction or RollbackTransaction.
Components you instantiate to participate in the transaction must
support transactions.
1 |
// Instance variables:<br>// CORBACurrent corbcurr<br>// Connection myconnect<br> <br><br>int li_rc<br>long ll_rc<br>boolean lb_rc, lb_success<br> <br>ll_rc = myconnect.CreateInstance(mycomponent)<br>li_rc = this.GetContextService("CORBACurrent", & <br> corbcurr)<br>IF li_rc <> 1 THEN<br> // handle error<br> RETURN<br>END IF<br> <br>li_rc = corbcurr.<span>Init</span>( myconnect )<br>IF li_rc <> 0 THEN<br> // handle error<br> RETURN<br>END IF<br> <br>lb_rc = corbcurr.<span>BeginTransaction</span>()<br>// perform some processing on the server and<br>// test for success<br>...<br>IF lb_success THEN<br> corbcurr.<span>CommitTransaction</span>()<br>ELSE<br> corbcurr.<span>RollbackTransaction</span>()<br>END IF |
You cannot begin a second transaction until the first transaction
has been committed or rolled back.
If a component is marked as OTS style, EAServer does
not start a transaction when the component is instantiated. EAServer expects the component to
start a transaction by calling the BeginTransaction function
on an instance of a CORBACurrent object.
A component should not begin a transaction and then call SetComplete before committing
or rolling back the transaction. The transaction will be orphaned until
it either times out or is picked up by another transaction.
Getting information about the transaction
CORBACurrent provides two functions for obtaining information
about the transaction: GetStatus and GetTransactionName. GetStatus returns
an Integer that indicates whether the transaction
is active, has been marked for rollback, is in the prepare phase
or commit phase, or has been committed or rolled back. GetTransactionName returns
a String that identifies the current transaction.
It is intended for use in debugging.
Suspending and resuming a transaction
A calling thread can suspend a transaction while the thread
performs some non–transactional processing and then resume
it. SuspendTransaction returns a handle to the
transaction that can be passed to the ResumeTransaction function. ResumeTransaction can
be called from a different thread in the same execution context.
In this example, the transaction is reassociated with the same thread:
1 |
long ll_rc<br>unsignedlong ll_handle<br>...<br>ll_rc = corbcurr.BeginTransaction()<br>// do some transactional work<br>ll_handle = corbcurr.<span>SuspendTransaction</span>()<br>// do some non-transactional work<br>corbcurr.<span>ResumeTransaction</span>(ll_handle)<br>// do some more transactional work |
Setting a timeout period for transactions
A calling thread can specify a timeout period after which
a transaction will be rolled back. This example sets the timeout
period to three minutes (180 seconds):
1 |
integer li_rc<br> <br> |
1 |
li_rc = this.GetContextService("CORBACurrent", &<br> corbcurr)<br>IF li_rc <> 1 THEN<br> // handle error and return<br>END IF<br>li_rc = corbcurr.Init()<br>IF li_rc <> 1 THEN<br> // handle error and return<br>END IF<br>corbcurr.<span>SetTimeout</span>(180)<br>corbcurr.BeginTransaction() |