Defining how a component participates in transactions
Choose a transaction coordinator. The transaction coordinator manages the flow of transactions that involve more than one connection. “Transaction coordinators” describes the available options.
Specify the component’s transaction attribute. Each component has a transaction attribute that determines whether instances of the component participate in transactions. “Transactional component attribute” describes the attribute settings and their meanings.
Code methods to call EAServer’s transaction state primitives. Each method should call the appropriate transaction state primitive to reflect the state of the work that the component has contributed to the transaction. “Using transaction state primitives” describes the state primitives in detail.
Specify a transaction timeout period if needed. By default, transactions are never timed out. You can configure a finite timeout period in EAServer Manager. See “Transaction Timeout property” for more information.
All components installed in one server share the same transaction coordinator.
Choices for transaction coordinator include:
Java Transaction Service (JTS) This option complies with the JTS and the Object Transaction Service (OTS) and X/Open Architecture (XA) standards. The JTS transaction coordinator integrates the functionality of the shared connection, OTS/XA, and JTS/JTA transaction modes, and uses two-phase commit to coordinate transactions among multiple databases.
Microsoft Distributed Transaction Coordinator (DTC) DTC uses two-phase commit to coordinate transactions among multiple databases. DTC is available on Windows 2000 and Windows NT platforms as part of Microsoft SQL Server 6.5 or later versions.
DTC transaction support in EAServer requires the following:
Microsoft DTC must be installed and running on the server host.
Any database servers used by your application must be DTC- compliant.
Your components must connect to the DTC-compliant databases using an ODBC connection cache or a JDBC connection cache that uses the JDBC-ODBC driver.
To verify that your EAServer edition supports two-phase commit, check the server console or the $JAGUAR/bin/<server_name>.log file.
The default coordinator is the JTS coordinator. To view or change the coordinator, use the Server Properties dialog box in EAServer Manager.
More transaction coordinators may be added in the future. The components you create now will not have to be changed to take advantage of the new transaction coordinators as they become available.
Components in EAServer have a transaction attribute that indicates how a component participates in transactions. You can view and change a component’s transaction attribute using EAServer Manager; the attribute is displayed on the Transactions tab in the Component Properties window. For PowerBuilder components, you can specify the attribute in the PowerBuilder wizards (doing so ensures that it is saved with the PowerBuilder project and not overwritten by redeployment). The attribute has the following values:
Not Supported The Default. The component’s methods never execute as part of a transaction. If the component is activated by another component that is executing within a transaction, the new instance’s work is performed outside of the existing transaction.
Supports Transaction The component can execute in the context of an EAServer transaction, but a connection is not required in order to execute the component’s methods. If the component is instantiated directly by a base client, EAServer does not begin a transaction. If component A is instantiated by component B, and component B is executing within a transaction, component A executes in the same transaction.
Requires Transaction The component always executes in a transaction. When the component is instantiated directly by a base client, a new transaction begins. If component A is activated by component B, and B is executing within a transaction, then A executes within the same transaction; if B is not executing in a transaction, then A executes in a new transaction.
Requires New Transaction Whenever the component is instantiated, a new transaction begins. If component A is activated by component B, and B is executing within a transaction, then A begins a new transaction that is unaffected by the outcome of B’s transaction; if B is not executing in a transaction, then A executes in a new transaction.
Mandatory Methods may only be invoked by a client that has an outstanding transaction.
Bean Managed Uses EJB 1.1 transactional behavior. The component cannot inherit a client or other component’s transaction. The component can execute without a transaction or explicitly begin, commit, and roll back transactions by using the javax.transaction.UserTransaction interface (for EJB components) or the Current interface (for C++ components).
OTS Style Uses OTS transactional behavior. The component can inherit a client or other component’s transaction. If called without a transaction, the component can explicitly begin, commit, and roll back transactions by using the CORBA Current interface.
Current interface and OTS-style are incompatible Although you can set a Java-CORBA component's transaction attribute to OTS Style, you will not have access to the Current interface. Since an OTS-style component can inherit a transaction from a parent component, the component behaves as in the Supports Transactions attribute case.
Table 2-1 lists design scenarios and the transaction attributes that apply to each.
Design scenario |
Applicable transaction attributes |
---|---|
Your component interacts with remote databases, and its methods may be called by another component as part of a larger transaction. Multiple updates are issued before calling completeWork, or an update depends on the results of queries that were issued since the last call to completeWork. |
Requires Transaction or Requires New Transaction |
Updates from your component are performed by a single database update, the update logic is independent of any other query issued by the method, and you call completeWork in each method that issues an update. In other words, your component’s updates are already atomic. |
Supports Transaction |
Your component’s methods make intercomponent method calls, and the work done by called components must be included in one transaction. |
Requires Transaction or Requires New Transaction |
Methods in the component interact with more than one remote database, and updates to different databases must be grouped in the same transaction (this also requires a transaction coordinator that supports two-phase commit to those databases). |
Requires Transaction or Requires New Transaction |
Transactions begun by your component must not be affected by the outcome of transactions begun by other components that call your component. |
Requires New Transaction |
Work done by your component must never be done as part of a transaction. |
Not Supported |
For example, in the scenario illustrated in “A transaction involving multiple components”, the Enrollment component must be marked Requires Transaction or Requires New Transaction, since it calls methods in the Registrar and StudentBilling components, and the work performed by the called components must be grouped in a single transaction. Both Registrar and StudentBilling must be marked Supports Transaction or Requires Transaction so that their database updates can be grouped in the transaction begun by the Enrollment component.
Transaction Not Supported is useful when your component performs updates to a noncritical database. For example, consider a component whose sole function is to log usage statistics to a remote database. Since usage statistics are not mission-critical data, you can choose Not Supported as the component’s transaction attribute to ensure that the logging updates do not incur the overhead of using two-phase commit.
After a base client instantiates a transactional component, the first method invocation begins an EAServer transaction. This instance is said to be the root instance of the transaction. If the root instance invokes methods in other transactional components, those components join the existing transaction.
The outcome of the transaction is determined by how the participating components call the transaction state primitives discussed in “Using transaction state primitives”.
Use a stub or proxy object for the called component For transactions to occur with the intended semantics, you must perform intercomponent calls using a stub or proxy object for the called component. Do not invoke another component’s methods directly.
EAServer provides transaction state primitives that methods can call to direct the outcome of the current transaction. Each component model provides an interface containing methods for these primitives. Table 2-2 lists the API mappings for each component type.
These methods end a component’s participation in a transaction (both cause the current instance to be deactivated):
completeWork The component finished its work for the current transaction and should be deactivated when the method returns.
rollbackWork The component cannot complete its work. Doom the current transaction and deactivate the instance when the method returns.
These methods are used to maintain state after the method returns (they delay deactivation of the component instance):
continueWork Continue this component’s participation in the current transaction after the method returns, and allow the transaction to be committed if the component is deactivated. If a method calls no transaction primitive, this is the default behavior.
disallowCommit Continue this component’s participation in the current transaction after the method returns, but roll back the transaction if the component is deactivated before calling another primitive besides disallowCommit.
These primitives can be used to query the state of the transaction (if any) in which the method is executing:
isInTransaction Query whether the current method is executing in the context of a transaction.
isRollbackOnly Query whether the current transaction is doomed to be rolled back or is still viable.
The following table describes how the transaction primitives are invoked in Java and PowerBuilder components. For information on the Java methods, see Chapter 1, “Java Classes and Interfaces,” in the EAServer API Reference. For information on the PowerBuilder TransactionServer object, see the Application Techiques manual in the PowerBuilder documentation and the PowerBuilder online help.
Transaction primitive |
Java InstanceContext method |
PowerBuilder TransactionServer function |
---|---|---|
completeWork |
completeWork |
SetComplete |
rollbackWork |
rollbackWork |
SetAbort |
continueWork |
continueWork |
EnableCommit |
disallowCommit |
None. You can achieve the same effect by calling, and then raising an exception if deactivate is called before the next method invocation. |
DisableCommit |
isInTransaction |
inTransaction |
IsInTransaction |
isRollbackOnly |
isRollbackOnly |
IsTransactionAborted |
ActiveX, C, and C++ components call the methods and routines in the following table to invoke transaction primitives. See the EAServer API Reference for documentation of these methods and routines:
Transaction primitive |
ActiveX IObjectContext method |
C/C++ routine |
---|---|---|
completeWork |
SetComplete |
JagCompleteWork |
rollbackWork |
SetAbort |
JagRollbackWork |
continueWork |
EnableCommit |
JagContinueWork |
disallowCommit |
DisableCommit |
JagDisallowCommit |
isInTransaction |
IsInTransaction |
JagInTransaction |
isRollbackOnly |
Not supported |
JagIsRollbackOnly |
Any participating component can roll back the transaction by calling the rollbackWork primitive; Java components can also cause a rollback by returning an unhandled exception. Only the action of the root component determines when EAServer commits the transaction. The transaction is committed when the root component returns with a state of completeWork and no participating component has set a state of disallowCommit.
You can use the transaction state primitives in any component; the component does not have to be declared transactional. Calling completeWork or rollbackWork from methods causes early deactivation. “Supporting early deactivation in your component” discusses how this feature can improve application performance.
The root instance’s Transaction Timeout property specifies the maximum duration of an EAServer transaction. The default timeout period is infinite. You can configure finite timeouts in EAServer Manager, as described in “Component properties: Resources”.
A transaction begins when a base client activates a transactional component; this component is the root component of the transaction. The root component’s Transaction Timeout property determines the maximum duration of the transaction.
If the transaction is not committed or rolled back within the allotted time, it is automatically rolled back. In this case, the client receives the CORBA TRANSACTION_ROLLEDBACK exception when it tries another method invocation. The client’s object reference remains valid, and the transaction can be retried.
Transactions are never rolled back in the middle of a method invocation. If the timeout occurs during a method invocation, and the method does not commit the transaction, the transaction is rolled back when the invocation completes.
When using the UserTransaction interface,
the default timeout for transactions is 300 seconds (five minutes).
To change this value, edit the UserTxnManager.props file,
located in the EAServer Repository/Component/CosTransactions subdirectory,
and set the value of the com.sybase.jaguar.component.tx_timeout
property.
A value of “0” means no timeout exists. You can
also set the timeout value from a client (within a transaction it
initiated) or in a bean-managed server component with the UserTransactions method setTransactionTimeout(secs).
Copyright © 2005. Sybase Inc. All rights reserved. |