Getting Started with Oracle Tuxedo CORBA Applications

     Previous  Next    Open TOC in new window  Open Index in new window  View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

Using Transactions

This topic includes the following sections:

Note: This topic describes using the C++ interface to the CORBA Services Object Transaction service. For a complete description of all the transaction features available in the CORBA environment of the Oracle Tuxedo product and instructions for implementing the transaction features, see Using CORBA Transactions in the Oracle Tuxedo online documentation.
Note: The Oracle Tuxedo CORBA Java client and Oracle Tuxedo CORBA Java client ORB were deprecated in Tuxedo 8.1 and are no longer supported. All Oracle Tuxedo CORBA Java client and Oracle Tuxedo CORBA Java client ORB text references, associated code samples, should only be used to help implement/run third party Java ORB libraries, and for programmer reference only.
Note: Technical support for third party CORBA Java ORBs should be provided by their respective vendors. Oracle Tuxedo does not provide any technical support or documentation for third party CORBA Java ORBs.

 


Overview of the Transaction Service

One of the most fundamental features of the Oracle Tuxedo product is transaction management. Transactions are a means to guarantee that database transactions are completed accurately and that they take on all the ACID properties (atomicity, consistency, isolation, and durability) of a high-performance transaction. The Oracle Tuxedo system protects the integrity of your transactions by providing a complete infrastructure for ensuring that database updates are done accurately, even across a variety of resource managers.

The Oracle Tuxedo system uses the following:

The CORBA environment in the Oracle Tuxedo product provides a C++ interface to the Object Transaction Service. The OTS is accessed through the TransactionCurrent environmental object. For information about using the TransactionCurrent environmental object, see Creating CORBA Client Applications in the Oracle Tuxedo online documentation.

OTS provides the following support for your business transactions:

 


What Happens During a Transaction

Figure 5-1 illustrates how transactions work in a Oracle Tuxedo CORBA application.

Figure 5-1 How Transactions Work in a Oracle Tuxedo CORBA Application

How Transactions Work in a Oracle Tuxedo CORBA Application

A basic transaction works in the following way:

  1. The client application uses the Bootstrap object to return an object reference to the TransactionCurrent object for the Oracle Tuxedo domain.
  2. A client application begins a transaction using the Tobj::TransactionCurrent::begin() method, and issues a request to the CORBA interface through the TP Framework. All operations on the CORBA interface execute within the scope of a transaction.
    • If a call to any of these operations raises an exception (either explicitly or as a result of a communication failure), the exception can be caught and the transaction can be rolled back.
    • If no exceptions occur, the client application commits the current transaction using the Tobj::TransactionCurrent::commit() method. This method ends the transaction and starts the processing of the operation. The transaction is committed only if all of the participants in the transaction agree to commit.
  3. The Tobj::TransactionCurrent:commit() method causes the TP Framework to call the Transaction Manager to complete the transaction.
  4. The Transaction Manager updates the database.
Note: Oracle Tuxedo CORBA also supports the use of the CORBA Interoperable Naming Service (INS) to obtain an initial object reference for the Security Service. For information on the INS bootstrapping mechanism, see the CORBA Programming Reference.

 


Transactions Sample Application

In the Transactions sample application, the operation of registering for courses is executed within the scope of a transaction. The transaction model used in the Transactions sample application is a combination of the conversational model and the model in which a single client invocation invokes multiple individual operations on a database.

The Transactions sample application works in the following way:

  1. Students submit a list of courses for which they want to be registered.
  2. For each course in the list, the CORBA server application checks whether:
    • The course is in the database.
    • The student is already registered for a course.
    • The student exceeds the maximum number of credits the student can take.
  3. One of the following occurs:
    • If the course meets all the criteria, the CORBA server application registers the student for the course.
    • If the course is not in the database or if the student is already registered for the course, the CORBA server application adds the course to a list of courses for which the student could not be registered. After processing all the registration requests, the CORBA server application returns the list of courses for which registration failed. The CORBA client application can then choose to either commit the transaction (thereby registering the student for the courses for which registration request succeeded) or to roll back the transaction (thus, not registering the student for any of the courses).
    • If the student exceeds the maximum number of credits the student can take, the CORBA server application returns a TooManyCredits user exception to the CORBA client application. The CORBA client application provides a brief message explaining that the request was rejected. The CORBA client application then rolls back the transaction.

Figure 5-2 illustrates how the Transactions sample application works.

Figure 5-2 Transactions Sample Application

Transactions Sample Application

The Transactions sample application shows two ways in which a transaction can be rolled back:

 


Development Steps

This topic describes the development steps for writing a Oracle Tuxedo CORBA application that includes transactions. Table 5-1 lists the development steps.

Table 5-1 Development Steps for Oracle Tuxedo CORBA Applications That Have Transactions
Step
Description
1
Write the OMG IDL code for the transactional CORBA interface.
2
Define the transaction policies for the CORBA interface in the Implementation Configuration file (ICF).
3
Write the CORBA client application.
4
Write the CORBA server application.
5
Create a configuration file.

The Transactions sample application is used to demonstrate these development steps. The source files for the Transactions sample application are located in the \samples\corba\university directory of the Oracle Tuxedo software. For information about building and running the Transactions sample application, see Guide to the CORBA University Sample Application in the Oracle Tuxedo online documentation.

 


Step 1: Write the OMG IDL Code

You need to specify interfaces involved in transactions in Object Management Group (OMG) Interface Definition Language (IDL) just as you would any other CORBA interface. You must also specify any user exceptions that may occur from using the interface.

For the Transactions sample application, you would define in OMG IDL the Registrar interface and the register_for_courses() operation. The register_for_courses() operation has a parameter, NotRegisteredList, which returns to the CORBA client application the list of courses for which registration failed. If the value of NotRegisteredList is empty, the CORBA client application commits the transaction. You also need to define the TooManyCredits user exception.

Listing 5-1 includes the OMG IDL code for the Transactions sample application.

Listing 5-1 OMG IDL Code for the Transactions Sample Application
#pragma prefix "beasys.com"
module UniversityT
{
typedef unsigned long CourseNumber;
typedef sequence<CourseNumber> CourseNumberList;

struct CourseSynopsis
{
CourseNumber course_number;
string title;
};
typedef sequence<CourseSynopsis> CourseSynopsisList;

interface CourseSynopsisEnumerator
{
//Returns a list of length 0 if there are no more entries
CourseSynopsisList get_next_n(
in unsigned long number_to_get, // 0 = return all
out unsigned long number_remaining
);

void destroy();
};
typedef unsigned short Days;
const Days MONDAY = 1;
const Days TUESDAY = 2;
const Days WEDNESDAY = 4;
const Days THURSDAY = 8;
const Days FRIDAY = 16;
//Classes restricted to same time block on all scheduled days, 
//starting on the hour
struct ClassSchedule
{
Days class_days; // bitmask of days
unsigned short start_hour; // whole hours in military time
unsigned short duration; // minutes
};
struct CourseDetails
{
CourseNumber course_number;
double cost;
unsigned short number_of_credits;
ClassSchedule class_schedule;
unsigned short number_of_seats;
string title;
string professor;
string description;
};
typedef sequence<CourseDetails> CourseDetailsList;
typedef unsigned long StudentId;
struct StudentDetails
{
StudentId student_id;
string name;
CourseDetailsList registered_courses;
};
enum NotRegisteredReason
{
AlreadyRegistered,
NoSuchCourse
};
struct NotRegistered
{
CourseNumber course_number;
NotRegisteredReason not_registered_reason;
};
typedef sequence<NotRegistered> NotRegisteredList;
exception TooManyCredits
{
unsigned short maximum_credits;
};
//The Registrar interface is the main interface that allows
//students to access the database.
interface Registrar
{
CourseSynopsisList
get_courses_synopsis(
in string search_criteria,
in unsigned long number_to_get,
out unsigned long number_remaining,
out CourseSynopsisEnumerator rest);
   	CourseDetailsList get_courses_details(in CourseNumberList
courses);
StudentDetails get_student_details(in StudentId student);
NotRegisteredList register_for_courses(
in StudentId student,
in CourseNumberList courses
) raises (
TooManyCredits
);
};
// The RegistrarFactory interface finds Registrar interfaces.
interface RegistrarFactory
{
Registrar find_registrar(
);
};

Step 2: Define Transaction Policies for the Interfaces

Transaction policies are used on a per-interface basis. During design, it is decided which interfaces within a Oracle Tuxedo CORBA application will handle transactions. The transaction policies are listed in the following table.

Transaction Policy
Description
always
The interface must always be part of a transaction. If the interface is not part of a transaction, a transaction will be automatically started by the TP Framework.
ignore
The interface is not transactional; however, requests made to this interface within a scope of a transaction are allowed. The AUTOTRAN parameter, specified in the UBBCONFIG file for this interface, is ignored.
never
The interface is not transactional. Objects created for this interface can never be involved in a transaction. The Oracle Tuxedo system generates the INVALID_TRANSACTION exception if an interface with this policy is involved in a transaction.
optional
The interface might be transactional. Objects can be involved in a transaction if the request is transactional. This transaction policy is the default.

Note: To define transactional properties for a request you can also use the autotran parameter.

During development, you decide which interfaces will execute in a transaction by assigning transaction policies.

For CORBA server applications, you specify transaction policies in the Implementation Configuration File (ICF). A template ICF file is created when you run the genicf command.

In the Transactions sample application, the transaction policy of the Registrar interface is set to always.

Step 3: Write the CORBA Client Application

The CORBA client application needs code that performs the following tasks:

  1. Obtains a reference to the TransactionCurrent or TransactionFactory object from the Bootstrap object.
  2. Begins a transaction by invoking the Tobj::TransactionCurrent::begin() operation on the TransactionCurrent object.
  3. Invokes operations on the object. In the Transactions sample application, the CORBA client application invokes the register_for_courses() operation on the Registrar object, passing a list of courses.

Listing 5-2 illustrates the portion of the CORBA C++ client application in the Transactions sample application that illustrates the development steps for transactions.

Listing 5-2 Transactions Code for CORBA C++ Client Applications
CORBA::Object_var var_transaction_current_oref =  
Bootstrap.resolve_initial_references("TransactionCurrent");
CosTransactions::Current_var var_transaction_current_ref=
CosTransactions::Current::_narrow(var_transaction_current_oref.in());
//Begin the transaction
var_transaction_current_ref->begin();
try {
// Perform the operation inside the transaction
pointer_Registar_ref->register_for_courses(student_id, course_number_list);
// ...
// If operation executes with no errors, commit the transaction:
CORBA::Boolean report_heuristics = CORBA_TRUE;
var_transaction_current_ref->commit(report_heuristics);
}
catch (...) {
// If the operation has problems executing, rollback the
// transaction. Then throw the original exception again.
// If the rollback fails, ignore the exception and throw the
// original exception again.
try {
var_transaction_current_ref->rollback();
}
catch (...) {
TP::userlog("rollback failed");
}
throw;
}

Step 4: Write the CORBA Server Application

When using transactions in CORBA server applications, you need to write methods that implement the interface’s operations. In the Transactions sample application, you would write a method implementation for the register_for_courses() operation.

If your Oracle Tuxedo CORBA application uses a database, you need to include code in the CORBA server application that opens and closes an XA resource manager. These operations are included in the Server::initialize() and Server::release() operations of the Server object.

Listing 5-3 shows the portion of the code for the Server object in the Transactions sample application that opens and closes the XA resource manager.

Note: For a complete example of a C++ server application that implements transactions, see the Transactions sample application in Using CORBA Transactions in the Oracle Tuxedo online documentation.
Listing 5-3 C++ Server Object in Transactions Sample Application
CORBA::Boolean Server::initialize(int argc, char* argv[])
{
TRACE_METHOD("Server::initialize");
try {
open_database();
begin_transactional();
register_fact();
return CORBA_TRUE;
}
catch (CORBA::Exception& e) {
LOG("CORBA exception : " <<e);
}
catch (SamplesDBException& e) {
LOG("Can’t connect to database");
}
catch (...) {
LOG("Unexpected exception");
}
cleanup();
return CORBA_FALSE;
}
void Server::release()
{
TRACE_METHOD("Server::release");
cleanup();
}
static void cleanup()
{
unregister_factory();
end_transactional();
close_database();
}

// Utilities to manage transaction resource manager
CORBA::Boolean s_became_transactional = CORBA_FALSE;
static void begin_transactional()
{
TP::open_xa_rm();
s_became_transactional = CORBA_TRUE;
}
static void end_transactional()
{
if(!s_became_transactional){
// cleanup not necessary
return;
}
try {
TP::close_xa_rm ();
}
catch (CORBA::Exception& e) {
LOG("CORBA Exception : " << e);
}
catch (...) {
LOG("unexpected exception");
}
s_became_transactional = CORBA_FALSE;
}

Step 5: Create a Configuration File

You need to add the following information to the configuration file for a transactional Oracle Tuxedo CORBA application.

Listing 5-4 includes the portions of the configuration file that define this information for the Transactions sample application.

Listing 5-4 Configuration File for Transactions Sample Application
*RESOURCES
IPCKEY 55432
DOMAINID university
MASTER SITE1
MODEL SHM
LDBAL N
SECURITY APP_PW
*MACHINES
BLOTTO
LMID = SITE1
APPDIR = C:\TRANSACTION_SAMPLE
TUXCONFIG=C:\TRANSACTION_SAMPLE\tuxconfig
TLOGDEVICE=C:\APP_DIR\TLOG
TLOGNAME=TLOG
TUXDIR="C:\tuxdir"
MAXWSCLIENTS=10
*GROUPS
SYS_GRP
LMID = SITE1
GRPNO = 1
ORA_GRP
LMID = SITE1
GRPNO = 2
	OPENINFO  = "ORACLE_XA:Oracle_XA+SqlNet=ORCL+Acc=P
/scott/tiger+SesTm=100+LogDir=.+MaxCur=5"
OPENINFO = "ORACLE_XA:Oracle_XA+Acc=P/scott/tiger
+SesTm=100+LogDir=.+MaxCur=5"
CLOSEINFO = ""
TMSNAME = "TMS_ORA"
*SERVERS
DEFAULT:
RESTART = Y
MAXGEN = 5

TMSYSEVT
SRVGRP = SYS_GRP
SRVID = 1
	TMFFNAME
SRVGRP = SYS_GRP
SRVID = 2
CLOPT = "-A -- -N -M"
	TMFFNAME
SRVGRP = SYS_GRP
SRVID = 3
CLOPT = "-A -- -N"
	TMFFNAME
SRVGRP = SYS_GRP
SRVID = 4
CLOPT = "-A -- -F"
	TMIFRSVR
SRVGRP = SYS_GRP
SRVID = 5

UNIVT_SERVER
SRVGRP = ORA_GRP
SRVID = 1
RESTART = N
   	ISL
SRVGRP = SYS_GRP
SRVID = 6
CLOPT = -A -- -n //MACHINENAME:2500
*SERVICES

For information about the transaction log and defining parameters in the Configuration file, see Setting Up a Oracle Tuxedo Application in the Oracle Tuxedo online documentation.


  Back to Top       Previous  Next