|
|
This topic includes the following sections:
These sections describe how to integrate transactions into a WebLogic Enterprise (WLE) server application. Before you begin, you should read Introducing Transactions.
This topic includes the following sections:
Integrating Transactions in a WLE Client and Server Application
WLE supports transactions in the following ways:
Transaction Support in CORBA Applications
When an object is polled, the object may veto the current transaction by invoking rollback_only() on the TransactionCurrent object. In addition, if the current transaction is to be rolled back, objects have an opportunity to skip any writes to a database. If no object vetoes the current transaction, the transaction is committed.
The following sections explain how you can use object activation policies and transaction policies to determine the transactional behavior you want in your objects. Note that these policies apply to an interface and, therefore, to all operations on all objects implementing that interface.
Note:
If a server application manages an object that you want to be able to participate in a transaction, the Server
object for that application must invoke the com.beasys.Tobj.TP.open_xa_rm
and com.beasys.Tobj.TP.close_xa_rm
methods (in Java), or the TP::open_xa_rm()
and TP::close_xa_rm()
operations (in C++). For more information about database connections, see Opening an XA Resource Manager.
The WLE system provides the always
transactional policy, which you can define on an object's interface to have the WLE system start a transaction automatically when that object is invoked and a transaction has not already been scoped. When an invocation on that object is completed, the WLE system commits or rolls back the transaction automatically. Neither the server application, nor the object implementation, needs to invoke the TransactionCurrent
object in this situation; the WLE system automatically invokes the TransactionCurrent
object on behalf of the server application.
Assign the always
transactional policy to an object's interface when:
Making an Object Automatically Transactional
If you want an object to be automatically transactional, assign the following policies to that object's interface in the XML-based Server Description File (in Java) or Implementation Configuration File (in C++):
Activation Policies |
Transaction Policy |
---|---|
Note:
Database cursors cannot span transactions. However, in C++, the CourseSynopsisEnumerator
object in the WLE University sample applications uses a database cursor to find matching course synopses from the University database. Because database cursors cannot span transactions, the activate_object()
operation on the CourseSynopsisEnumerator
object reads all matching course synopses into memory. Note that the cursor is managed by an iterator class and is thus not visible to the CourseSynopsisEnumerator
object.
If you want an object to be able to be invoked within the scope of a transaction, you can assign the optional
transaction policies to that object's interface. The optional
transaction policy may be appropriate for an object that does not perform any database write operations, but that you want to have the ability to be invoked during a transaction.
You can use the following policies, when they are specified in the XML-based Server Description File (in Java) or Implementation Configuration File (in C++) for that object's interface, to make an object optionally transactional:
Enabling an Object to Participate in a Transaction
Activation Policies |
Transaction Policy |
---|---|
When the transaction policy is optional
, if the AUTOTRAN
parameter is enabled in the application's UBBCONFIG
file, the implementation is transactional. Servers containing transactional objects must be configured within a group associated with an XA-compliant Resource Manager.
If the object does perform database write operations, and you want the object to be able to participate in a transaction, assigning the always
transactional policy is generally a better choice. However, if you prefer, you can use the optional
policy and encapsulate any write operations within invocations on the TransactionCurrent
object. That is, within your operations that write data, scope a transaction around the write statements by invoking the TransactionCurrent
object to, respectively, begin and commit or roll back the transaction, if the object is not already scoped within a transaction. This ensures that any database write operations are handled transactionally. This also introduces a performance efficiency: if the object is not invoked within the scope of a transaction, all the database read operations are nontransactional, and, therefore, more streamlined.
Note:
When choosing the transaction policies to assign to your objects, make sure you are familiar with the requirements of the XA Resource Manager you are using. For example, some XA Resource Managers (such as the Oracle 7 Transaction Manager Server) require that any object participating in a transaction scope their database read operations, in addition to write operations, within a transaction (you can still scope your own transactions, however). Other Resource Managers, such as Oracle8i, do not require a transaction context for read and write operations. If an application attempts a write operation without a transaction context, Oracle8i will start a local transaction implicitly, in which case the application needs to commit the local transaction explicitly.
In many cases, it may be critical to exclude an object from a transaction. If such an object is invoked during a transaction, the object returns an exception, which may cause the transaction to be rolled back. The WLE system provides the never
transaction policy, which you can assign to an object's interface to specifically prevent that object from being invoked within the course of a transaction, even if the current transaction is suspended.
This transaction policy is appropriate for objects that write durable state to disk that cannot be rolled back, such as for an object that writes data to a disk that is not managed by an XA Resource Manager. Having this capability in your client/server application is crucial if the client application does not or cannot know if some of its invocations are causing a transaction to be scoped. Therefore, if a transaction is scoped, and an object with this policy is invoked, the transaction can be rolled back.
To prevent an object from being invoked while a transaction is scoped, assign the following policies to that object's interface in the XML-based Server Description File (in Java) or Implementation Configuration File (in C++):
Preventing an Object from Being Invoked While a Transaction Is Scoped
Activation Policies |
Transaction Policy |
---|---|
In some cases, it may be appropriate to permit an object to be invoked during the course of a transaction but also keep that object from being a part of the transaction. If such an object is invoked during a transaction, the transaction is automatically suspended. After the invocation on the object is completed, the transaction is automatically resumed. The WLE system provides the ignore
transaction policy for this purpose.
The ignore
transaction policy may be appropriate for an object such as a factory that typically does not write data to disk. By excluding the factory from the transaction, the factory can be available to other client invocations during the course of a transaction. In addition, using this policy can introduce an efficiency into your server application because it minimizes the overhead of invoking objects transactionally.
To prevent any transaction from being propagated to an object, assign the following policies to that object's interface in the Server Description File (in Java) or Implementation Configuration File (in C++):
Excluding an Object from an Ongoing Transaction
Activation Policies |
Transaction Policy |
---|---|
For information about how to create a Server Description File (in Java) or Implementation Configuration File (in C++) and specify policies on objects, see "Step 5: Define the object activation and transaction policies" in "Steps for Creating a WLE Server Application" in Creating Java Server Applications, or "Step 4: Define the in-memory behavior of objects" in "Steps for Creating a WLE Server Application" in Creating C++ Server Applications.
The Transaction Manager Server (TMS) handles object state data automatically. For example, the XA Bankapp sample C++ application in the drive:\M3dir\samples\corba\bankapp_java\XA
directory uses the Oracle7 TMS as an example of a relational database management service (RDBMS).
Using any XA Resource Manager imposes specific requirements on how different objects managed by the server application may read and write data to that database, including the following:
Assigning Policies
Using an XA Resource Manager
Other XA Resource Managers, such as Oracle8i, do not require a transaction context for read and write operations. If an application attempts a write operation without a transaction context, Oracle8i will start a local transaction implicitly, in which case the application needs to commit the local transaction explicitly.
This characteristic of XA Resource Managers actually makes the design problems associated with handling object state data in the event of a rollback much simpler. Transactional objects can always delegate the commit and rollback responsibilities to the XA Resource Manager, which greatly simplifies the task of implementing a server application.
This section describes how to open the XA Resource Manager in Java and C++.
If an object's interface has the always
or optional
transaction policy, you must invoke the com.beasys.Tobj.TP.open_xa_rm
method in the com.beasys.Tobj.Server.initialize
method in the Server object that supports this object. You must build a special version of the JavaServer by using the buildXAJS
command, if your object performs database operations.
In the SERVERS
section of the application's UBBCONFIG
file, you must use the JavaServerXA
element in place of JavaServer
to associate the XA Resource Manager with a specified server group. (JavaServer
uses the null RM.)
The Resource Manager is opened using the information provided in the OPENINFO
parameter, which is in the GROUPS
section of the UBBCONFIG
file. Note that the default version of the com.beasys.Tobj.Server.initialize
method automatically opens the Resource Manager.
If you have an object that participates in a transaction but does not actually perform database operations (the object typically has the optional
transaction policy), you still need to include an invocation to the com.beasys.Tobj.TP.open_xa_rm
method.
If an object's interface has the always
or optional
transaction policy, you must invoke the TP::open_xa_rm()
operation in the Server::initialize()
operation in the Server object. The Resource Manager is opened using the information provided in the OPENINFO
parameter, which is in the GROUPS
section of the UBBCONFIG
file. Note that the default version of the Server::initialize()
operation automatically opens the Resource Manager.
If you have an object that does not write data to disk and that participates in a transaction--the object typically has the optional
transaction policy--you still need to include an invocation to the TP::open_xa_rm()
operation. In that invocation, specify the NULL
Resource Manager.
If your Server object's com.beasys.Tobj.Server.initialize
method (in Java) or Server::initialize()
operation (in C++) opens an XA Resource Manager, you must include the following invocation in the com.beasys.Tobj.Server.release
method (in Java) or Server::release()
operation (in C++):
Java:
com.beasys.Tobj.TP.close_xa_rm(); C++:
TP::close_xa_rm(); This topic includes the following sections:
Opening an XA Resource Manager
Opening an XA Resource Manager in Java
Opening an XA Resource Manager in C++
Closing an XA Resource Manager
Transactions and Object State Management
If you need transactions in your WLE client and server application, you can integrate transactions with object state management in a few different ways. In general, the WLE system can automatically scope the transaction for the duration of an operation invocation without requiring you to make any changes to your application's logic or the way in which the object writes durable state to disk.
Using an XA Resource Manager, such as Oracle7, generally simplifies the design problems associated with handling object state data in the event of a rollback. (The Oracle7 Resource Manager is used in the WLE University sample C++ applications). Transactional objects can always delegate the commit and rollback responsibilities to the XA Resource Manager, which greatly simplifies the task of implementing a server application. This means that process- or method-bound objects involved in a transaction can write to a database during transactions, and can depend on the Resource Manager to undo any data written to the database in the event of a transaction rollback.
The transaction
activation policy is a good choice for objects that maintain state in memory that you do not want written, or that cannot be written, to disk until the transaction work is complete. When you assign the transaction
activation policy to an object, the object:
Delegating Object State Management to an XA Resource Manager
Waiting Until Transaction Work Is Complete Before Writing to the Database
When the transaction work is complete, the WLE system invokes each transaction-bound object's com.beasys.Tobj_Servant.deactivate_object
method (in Java) or Tobj_ServantBase::deactivate_object()
operation (in C++), passing a reason
code that can be either DR_TRANS_COMMITTING
or DR_TRANS_ABORTED
. If the variable is DR_TRANS_COMMITTING
, the object can invoke its database write operations. If the variable is DR_TRANS_ABORTED
, the object skips its write operations.
Assigning the transaction
activation policy to an object may be appropriate in the following situations:
When to Assign the Transaction Activation Policy
This introduces a performance efficiency because it reduces the number of database write operations that may need to be rolled back.
If the WLE system passes the reason DR_TRANS_COMMITTING , the object can, if necessary, invoke rollback_only() on the TransactionCurrent object. Note that if you do make an invocation to rollback_only() from within the com.beasys.Tobj_Servant.deactivate_object method (in Java) or Tobj_ServantBase::deactivate_object() operation (in C++), then deactivate_object() is not invoked again.
To give an object the ability to wait until the transaction is committing before writing to a database, assign the following policies to that object's interface in the XML-based Server Description File (in Java) or Implementation Configuration File (in C++):
Transaction Policies to Use with the Transaction Activation Policy
Activation Policy |
Transaction Policy |
---|---|
Note:
Transaction-bound objects cannot start a transaction or invoke other objects from inside the com.beasys.Tobj_Servant.deactivate_object
method (in Java) or Tobj_ServantBase::deactivate_object()
operation (in C++). The only valid invocations transaction-bound objects can make inside deactivate_object()
are write operations to the database.
Also, if you have an object that is involved in a transaction, the Server object that manages that object must include invocations to open and close the XA Resource Manager, even if the object does not write any data to disk. (If you have a transactional object that does not write data to disk, you specify the NULL
Resource Manager.) For more information about opening and closing an XA Resource Manager, see Opening an XA Resource Manager and Closing an XA Resource Manager.
This topic includes the following sections:
User-Defined Exceptions
Including a user-defined exception in a WLE client/server application involves the following steps:
About User-Defined Exceptions
For example, the Transactions sample C++ application includes an instance of a user-defined exception, TooManyCredits . This exception is thrown by the server application when the client application tries to register a student for a course, and the student has exceeded the maximum number of courses for which he or she can register. When the client application catches this exception, the client application rolls back the transaction that registers a student for a course. This section explains how you can define and implement user-defined exceptions in your WLE client/server application, using the TooManyCredits exception as an example.
In the OMG IDL file for your client/server application:
exception TooManyCredits
{
unsigned short maximum_credits;
};
NotRegisteredList register_for_courses(
in StudentId student,
in CourseNumberList courses
) raises (
TooManyCredits
);
In the implementation of the operation that uses the exception, write the code that throws the exception, as in the following C++ example.
if ( ... ) {
UniversityZ::TooManyCredits e;
e.maximum_credits = 18;
throw e;
This topic includes the following sections:
To implement the student registration process, the Transactions sample application does the following:
About the Transactions University Sample Application
The Registrar object checks for the following potential problems, which prevent the transaction from being committed:
If the NotRegisteredList value is empty, the client application commits the transaction.
If the NotRegisteredList value contains any courses, the client application queries the student to indicate whether he or she wants to complete the registration process for the courses for which the registration succeeded. If the user chooses to complete the registration, the client application commits the transaction. If the user chooses to cancel the registration, the client application rolls back the transaction.
The basic design rationale for the Transactions sample application is to handle course registrations in groups, as opposed to one at a time. This design helps to minimize the number of remote invocations on the Registrar
object.
In implementing this design, the Transactions sample application shows one model of the use of transactions, which were described in Integrating Transactions in a WLE Client and Server Application. The model is as follows:
Transactional Model Used by the Transactions University Sample Application
The Registrar object registers the student for the courses for which it can, and then returns a list of courses for which the registration process was unsuccessful. The client application can choose to commit the transaction or roll it back. The transaction encapsulates this conversation between the client and the server application.
Because the Transactions University sample application is transactional, the University server application generally needs to consider the implications on object state, particularly in the event of a rollback. In cases where there is a rollback, the server application must ensure that all affected objects have their durable state restored to the proper state.
Because the Registrar
object is being used for database transactions, a good design choice for this object is to make it transactional (assign the always
transaction policy to this object's interface). If a transaction has not already been scoped when this object is invoked, the WLE system will start a transaction automatically.
By making the Registrar
object automatically transactional, all database write operations performed by this object will always be done within the scope of a transaction, regardless of whether the client application starts one. Since the server application uses an XA Resource Manager, and since the object is guaranteed to be in a transaction when the object writes to a database, the object does not have any rollback or commit responsibilities because the XA Resource Manager takes responsibility for these database operations on behalf of the object.
The RegistrarFactory
object, however, can be excluded from transactions because this object does not manage data that is used during the course of a transaction. By excluding this object from transactions, you minimize the processing overhead implied by transactions.
To make the Registrar
object transactional, the ICF file specifies the always
transaction policy for the Registrar
interface. Therefore, in the Transaction sample application, the ICF file specifies the following object policies for the Registrar
interface:
Object State Considerations for the University Server Application
Object Policies Defined for the Registrar Object
Activation Policy |
Transaction Policy |
---|---|
To exclude the RegistrarFactory
object from transactions, the ICF file specifies the ignore
transaction policy for the Registrar
interface. Therefore, in the Transaction sample application, the ICF file specifies the following object policies for the RegistrarFactory
interface:
Object Policies Defined for the RegistrarFactory Object
Activation Policy |
Transaction Policy |
---|---|
The Transactions sample application uses the Oracle7 Transaction Manager Server (TMS), which handles object state data automatically. Using any XA Resource Manager imposes specific requirements on how different objects managed by the server application may read and write data to that database, including the following:
Using an XA Resource Manager in the Transactions Sample Application
This characteristic of XA Resource Managers actually makes the design problems associated with handling object state data in the event of a rollback much simpler. Transactional objects can always delegate the commit and rollback responsibilities to the XA Resource Manager, which greatly simplifies the task of implementing a server application.
The University sample applications use an Oracle7 Transaction Manager Server (TMS). To use the Oracle7 database, you must include specific Oracle-provided files in the server application build process. For more information about building, configuring, and running the Transactions sample application, see Transactions Sample CORBA C++ XA Application. For more information about the configurable settings in the UBBCONFIG file, see Modifying the UBBCONFIG File to Accommodate Transactions.
Configuration Requirements for the Transactions Sample Application
|
Copyright © 1999 BEA Systems, Inc. All rights reserved.
|