VisiTransact Guide : Server Application Model

Server Application Model
This section describes the server application model supported by VisiTransact, as well as the XA configuration. With this model, the transaction logic becomes transparent to application business logic.
Server Application transaction and database management
The OMG Object Transaction Se rvice (OTS) specification (version 1.4 or below) standardizes the following aspects of distributed transactional applications:
OTS does not address application server-side database integration and the implicit transaction programming model. On the server side, by OMG OTS specification, applications are responsible for database connection and transaction control explicitly through the XA interface.
Using the ITS server application model, transaction control (and database connection) does not need to be handled by servant business logic implementation, but becomes an attribute setting specified as POA creation policy.
Requirements before reading this section
This section assumes the following knowledge:
Database and Embedded SQL You must know how to use database tools (such as Oracle sqlplus) to create, browse and manipulate database tables. You should be able to program in embedded SQL, and build applications with the database-provided embedded SQL to C++ pre-compiler (such as Oracle proc).
XML and DTD You must know how to use XML to describe XA configurations and you must understand Data Type Definition (DTD).
OMG and the Distributed Transaction Process (DTP) of X/Open You should know the DTP architecture concepts and terminology, as well as the client side implicit transaction programming model (using the transaction Current interface to start and end a transaction). You do not need to read through and understand the entire OMG OTS specification.
XA and database connection configuration You must be able to make minor modifications to XA and database configurations. 
Understanding the terminology of Container Managed Transaction (CMT), a concept of EJB and CCM, and the concepts of implementation, deployment, and application assembly in either EJB or CCM will help you use the information in this section.
Concepts and terminology
The following terminology is used in this section:
Client A CORBA application. See Client-initiated transaction (CIT) below for more information.
AP A CORBA client application that can initiate a transaction.
Server A CORBA server application that implements business logic. See RM and Server-initiated transaction (SIT) below for more information..
TM A Transaction Manager that coordinates global transactions. Typically, it is a stand-alone server process (such as a VisiTransact OTS server). In-proc TM is also supported in VisiTransact (ots.dll/so), but is not recommended.
RM A Resource Manager. In OMG OTS, RM usually refers to a database server. RM can also refer to an application server that uses SQL to access a database.
1PC One phase commit, involving a single RM, committed without a preparation stage.
2PC Two phase commit, involving multiple RMs, committed with a preparation stage.
Global transaction A transaction that can involve multiple RMs. Usually, but not necessarily, a global transaction needs to be coordinated by a TM and use a 2PC protocol to commit. See Local Transaction Optimization (LTO) below for more information. By default, all transactions described in this section are global transactions (initiated either by the client or the server).
Local transaction A transaction, which only involves one single RM, restricted in one thread of control, and not coordinated by TM.
Client-initiated transaction (CIT) Also known as a Client Demarcated Transaction, this term refers to a global transaction initiated and terminated by a client. Client-initiated transactions must be coordinated by a TM.
Server-initiated transaction (SIT) Also known as a Server Demarcated Transaction, this term refers to a global transaction initiated and terminated by a server PMT engine transparently when handling a client request. The boundary of this transaction is the given client request. The transaction starts before performing the business logic, and ends before replying to client. A server-initiated transaction is global, but not necessarily coordinated by a remote TM.
Note
SIT is a popular transaction model that is well documented and widely used in EJB and CCM (CORBA Component Model)
Local Transaction Optimization (LTO) A technique that allows a server to initiate and terminate a global transaction locally without involving a TM, if it only accesses one local RM (database). Server would only export a SIT to TM and evolve it into a true global transaction when server makes a forward call to a second RM (another transaction object outside the process). J2EE document presents a possible scenario of LTO, but not applicable to OTS implementation. Therefore, VisiTransact’s LTO uses a different technology to ensure it is OMG compliant, interoperable and applicable to other OTS implementations.
PMT POA Managed Transaction. A server side transaction and database integration engine. PMT separates and hides all database connection and transaction details from application business logic developers. With PMT, servant implementation business logic does not need to hardcode database connection and transaction logic within its implementation. Database connection and transaction control are independent of business logic, and can be configured and reconfigured during application assembling. With PMT, a given business logic implementation can involve both CIT and SIT. In addition, different operation signatures of a given object can be configured with different transaction attributes.
CosTransactions::Current A single object for client applications, in an implicit transaction model, to initiate and manipulate thread-specific global transaction. A server implementation can also use this object to retrieve thread-specific information about the global transaction it currently involves. The CosTransactions::Current can be retrieved from ORB using the resolve_initial_references() method.     
PMT::Current: A single object for a server application to retrieve information about thread specific database connection and transaction arranged by PMT engine. The retrieved information, such as connection name, is necessary for the SQL AT clause. Other retrieved information is useful for PMT diagnosis. PMT::Current object instance can be retrieved from PMT::Current::instance().
XA: An API standardized by X/Open. XA API drivers (usually shared libraries) are provided by database vendors. PMT uses these drivers to manipulate database connections and transactions. With PMT, XA (as well as database connections and transactions) are transparent to application developers. It is the responsibility of the application assembler to configure XA correctly. See “XA resources configuration” for more information.  
Session Manager (SM) A service used in previous releases. To use this service in this release, you must set the vbroker.its.its6xmode property to true. See “VisiTransact properties” for more information.
Resource Director (RD) A service used in previous releases. To use this service in this release, you must set the vbroker.its.its6xmode property to true. See “VisiTransact properties” for more information.
Scenarios of global transaction and PMT
Client-initiated global 2PC and 1PC transactions
In the OTS and X/Open DTP model, a distributed transaction means a global transaction initiated by a client. In this case, a client contacts a TM to initiate and end (commit or rollback) a transaction, regardless of whether it is 2PC (figure 1) or 1PC (figure 2).
Figure 23
 
Figure 24
Transparent server-initiated transactions with PMT
The PMT hides all transaction aspects from business logic developers and provides an optimized way to perform client-initiated or server-initiated global transactions.
For example, in a server-initiated transaction, PMT uses the local transaction optimization to initiate a global transaction locally, as shown in the following figure.
Figure 25
The locally-initiated global transaction is exported to an external TM before the server makes a forward invocation to another external transactional object, as shown in step 5 of the following figure.
Figure 26
PMT completely hides database access and transaction details. The server side implementation only needs to write Embedded SQL (or ODBC/CLI) to access an unspecified database, without specific database connection and transaction control statements. All database connection and transaction management tasks are performed, implicitly, by PMT integrated in the server-side ORB and POA engine. Consequently, the deposit() code is simplified, as shown in the following example:

void BankImpl::deposit(const char* id, float amount) {
EXEC SQL BEGIN DECLARE SECTION;
const char* account_id = id;
              float deposit_amount = amount;
        EXEC SQL END DECLARE SECTION;

EXEC SQL UPDATE account_table
WHERE account_id = :account_id
SET balance = balance + :deposit_amount;
}
There is neither connection management nor transaction management code. This same business logic implementation can be used transparently in either client-initiated or server-initiated transactions. 
PMT overview
PMT is set up programmatically. The server setup and transaction attribute configuration must be arranged in conventional POA creation code, namely POA creation policy.
PMT is modeled after the widely used Container Managed Transaction (CMT) of EJB and CCM. Therefore, most CMT concepts and features are directly applicable to PMT.
Note
Applications should not explicitly suspend or resume a transaction or obtain a transaction coordinator/termintator on a POA implicit managed transaction (PMT).
PMT transaction attribute values
In PMT, servant implementations only implement business logic. Details of transactions they are going to involve are determined by the transaction attribute assigned to specific objects and methods described in the policy of the POA PMT_ATTRS_TYPE. Using the POA policy, you can configure the transaction attributes as follows:
PMT_NotSupported
The propagation context is not copied to transaction current. POA neither joins the client’s transaction (T1), nor starts a server to initiate a new global transaction (T2). This is the default PMT attribute. This setting should be used for non-transactional methods to avoid the overhead of associating a current worker thread with a global transaction.
PMT_Required
POA joins or propagates the client-initiated global transaction (T1), if the request from the client carries a global transaction context. Otherwise, POA initiates and ends a new global transaction (T2) for that request. This is the most useful PMT attribute setting for transactional methods. It ensures the business logic will always be performed with an XA connection and within a transaction. This attribute is referred as “AUTOTRAN” in classic TP products.
PMT_Supports
POA joins or propagates the client-initiated global transaction (T1), if the request from client carries a global transaction context. Otherwise, if the request is not within a CIT, the POA does not start a transaction. When combined with a null XA resource (described in “XA resources configuration”), this PMT setting is typically used for transaction propagation.
PMT_RequiresNew
POA does not join or propagate a global transaction of a client, but always initiates and ends a new global transaction (T2) on each client request. To improve performance, use this PMT setting for all business logic with only a perform read (query) operation on backend databases.
PMT_Mandatory
POA always joins or propagates the global transactions of a client, if it is in a context. Otherwise, if the client did not start a transaction, POA raises an exception.
PMT_Never
POA raises an exception if it is in a client transaction context.
Note
PMT only applies to remote requests. Co-located invocations (although dispatched via POA), remain in client’s transaction, if any, regardless of the PMT setting. When POA initiated server transaction (T2) has not yet been exported to an external TM, calling method on transaction Current within servant implementation is prohibited.
The following table summarizes the PMT transaction attribute mode and its semantic behavior.
In a programmatic approach, an application can specify transaction attributes for a given POA and for given objects, at POA creation time, by specifying the PMT attribute policy.
The value of the PMT attribute POA creation policy is a sequence of PMTAttr structure, defined as follows:
module VISTransactions {
           …
           enum PMTMode {
                 PMT_NotSupported = 1,
PMT_Required = 2;
                 PMT_Supports = 3;
                 PMT_RequiresNew = 4;
              PMT_Mandatory = 5;
                 PMT_Never = 6;
   };

  struct PMTAttr {
          CORBA::OctetSequence     oid;
string                   method_name;
   PMTMode                  mode;
string                   xa_resource;                                     
    };

         typedef sequence<PMTAttr>  PMTAttrSeq;

};
In this definition of a PMTAttr structure:
The oid file specifies the ID of the object this PMT attribute setting applies to. If the oid is an empty sequence (zero length), this attribute setting applies to all objects of this POA. See the list of dynamic rules for more details.
The method_name field specifies the request operation name this PMT attribute setting applies to. If method_name is set to *, this attribute setting will apply to all request operations sending to objects of this POA.
The mode field specifies the mode of this PMT mode attribute setting.
The xa_resource field specifies the name of a preconfigured XA resource to be associated. For more information, see “XA resources configuration”. If this field is an empty string or null, a PortableServer::POA::InvalidPolicy exception is raised on create_POA(). Literal null is a special reserved xa-resource name. This name cannot be used to name a physical XA resource in an XA resource descriptor, but can only be used as value of the xa_resource field of PMTAttr. When a request condition matches one of the given PMTAttr with xa_resource field equal to null, the PMT engine does not associate the request processing worker thread with any physical XA connection. Instead, the PMT engine only ensures that the associated OTS context is propagated if the servant implementation method makes a forward invocation to the next tier. See the oci example in the <installation_directory>\examples\vbroker\Transaction directory.
It is possible that no, one, or two PMT attribute settings apply to a request. The PMT engine uses the following rules, in sequence, to decide which PMT mode or attribute should be applied:
1
2
3
4
5
6
PMT is independent of OMG standardized POA OTS policy. A Server side transaction engine first checks the target POA's OTS policy against the received request context, and decides whether to raise an OMG-specified exception (INVALID_TRANSACTION or TRANSACTION_REQUIRED). If no exception is raised, the request is forwarded to PMT.
A simple example
CORBA::PolicyList policies;
policies.length(1);

PortableServer::ObjectId_var objId= PortableServer::string_to_ObjectId("account_object");
PMTAttrSeq pmt_seq;
pmt_seq.length(1);

pmt_seq[0].oid = (CORBA::OctetSequence&) objId;
pmt_seq[0].method_name      = (const char*)“withdraw”;
pmt_seq[0].mode             = VISTransactions::PMT_Required;
pmt_seq[0].xa_resource      = (const char*)“account_storage”;

CORBA::Any policy_value;
policy_value <<= pmt_seq;
policies[0] = orb->create_policy(VISTransactions::PMT_ATTRS_TYPE, policy_value);

// Create myPOA with the right policies
PortableServer::POA_var myPOA = rootPOA->create_POA("account_server_poa",
poa_manager,
policies);
In this example:
A POA, which is PMT-enabled and has the name account_server_poa, is created.
Invocations on the target object with an ID of account_server_poa, an operation equal to withdraw is performed with the PMT_Required policy. It will either join the client-initiated transaction (T1), or, if the client did not initiate one, POA initiates a new global transaction (T2).
An xa-resource with the name account_storage is used by this transaction.
PMT::Current and connection name
OMG OTS defines the CosTransactions::Current object for an application to retrieve information and manipulate thread specific client-initiated transactions.
PMT also provides an additional object, PMT::Current, for applications to retrieve information about the transaction and connection associated to the thread by POA.
class PMT_Current {
public:
static const PMT_Current* instance();

const char*     resourceName() const;
const char*     connectionName() const;

// XA diagnoses
const xid_t*    xid() const;
int             rmid() const;

// PMT diagnoses (these two method does not raise exception)
int             attribute() const;
int             decision() const;
;
The name of the connection associated to the current work thread is returned by connectionName() of the current object. This name can be used to instruct an embedded SQL statement to use a specified connection, with either the AT <conn_name> clause or the SET CONNECTION <conn_name> statement, as shown in the following example: 
void BankImpl::deposit(const char* id, float amount) {
  EXEC SQL BEGIN DECLARE SECTION;
     const char* account_id = id;
            float deposit_amount = amount;
            const char* conn = current->connectionName();
       EXEC SQL END DECLARE SECTION;

      EXEC SQL
AT :conn UPDATE account_table
            WHERE account_id = :account_id
            SET balance = balance + :deposit_amount;
}
The connection name is similar to the concept of connection handle in Call Level Interface (CLI).
The AT clause in the previous example is optional in some cases. For example, Oracle has the concept of default connection, which is the connection last opened by the thread-of-control. If an embedded SQL does not have the AT clause, Oracle uses the default connection. Other databases, such as Sybase, do not have the concept of default connection, and Borland recommends using the AT clause or SET CONNECTION statement with those databases.
The following additional PMT::Current methods are used for diagnostic purposes.
const char* PMT::Current::resourceName() const:
Returns the XA resource name used by associated XA connection. See “XA resources configuration” for more information.
const xid_t* PMT::Current::xid() const:
Returns the XID of the transaction associated with the current thread. If no transaction is associated, this method raises a CosTransactions::unavailable exception.
int  rmid() const;
Returns the XA resource manager ID of the XA connection associated with the current thread. If no XA connections and no transactions are associated, this method raises a CosTransactions::Unavailable exception.
int  attribute() const;
Returns the PMT attribute mode of the PMT attribute that matches or wildcard matches with the current {POA, oid, method-name} triplex. If PMT is not enabled on the POA, the return value is 0.
int  decision() const;
Returns a value 1 or 2, indicating the current thread is associated with a client or server-initiated transaction. If PMT is not enabled on the POA, the return value is 0.
XA resources configuration
xa-resource-descriptor
In VisiTransact, XA resources are also configured using an XML description named xa-resource-descriptor. An xa-resource-descriptor is the root element of an xa-resource-descriptor XML file, which typically has following structure:
<?xml version="1.0"?>
<!DOCTYPE xa-resource-descriptor SYSTEM "xaresdesc.dtd">

<!-- an example of xa-resource-descriptor -->
<xa-resource-descriptor>
          …
          
</xa-resource-descriptor>
The <xa-resource-descriptor> root element can have one or multiple <xa-resource> sub-elements, and follow by zero or multiple <xa-resource-alias> elements with the following structure:

<!ELEMENT xa-resource-descriptor
        (xa-resource+,
        xa-resource-alias*)
&gt
xa-resource
An <xa-resource> defines and configures an XA resource supplier. Its sub-elements, <xa-connection> define connections to be opened on the given xa-resource. The DTD of an <xa-resource> is:
!ELEMENT xa-resource
(xa-connection+)
>&
ATTLIST xa-resource
name CDATA             "default"
xa-library CDATA             #IMPLIED
xa-switch CDATA             #REQUIRED
xa-conn-scope (thread|process) #REQUIRED
>
An <xa-resource> specifies one or more <xa-connection> sub-elements. It can be used to configure the following attributes:
name
Specifies a unique name for this xa-resource. This name is used by the PMT <transaction> element to decide which xa-resource the dispatched request should be associated with. The default value is default.
xa-library
Specifies the library file name of the XA API library, provided by database vendor. If this attribute is left out, the engine will try to resolve the XA from the application executable module itself.
xa-switch:  Specifies the symbol of the xa_switch_t variable.  For example, for Oracle XA, the symbol is xaosw, for Informix, the symbol is infx_xa_switch, and for DB2, the symbol is db2xa_switch.
xa-conn-scope: Specifies the scope of XA connection provided by the XA library. This depends on the XA API library that is used, and on the used XA open string (the info attribute in the <xa-connection> element).
Avoid the xa-conn-scope=”process” mode for Oracle XA because the Oracle XA library is not thread-safe when “+Threads=false”.
xa-connection
The <xa-connection> element specifies a given XA connection’s name and xa_open info string. The DTD of <xa-connection> element is:
<!ELEMENT xa-connection
EMPTY
>
<!ATTLIST xa-connection
name CDATA             #IMPLIED
info CDATA             #REQUIRED
name
Name of the connection. This name is returned from PMT::Current::connectName() method when the connection is associated with the thread. You must ensure that this name is consistent with the name assigned in the info string.
info
The string passed to xa_open(). The information specified by this string is XA provider dependent. The following table shows typical setting templates:
Using the information you provide, the PMT XA engine opens XA open connections. If the value of the xa-conn-scope attribute of <xa-resource> is process, VisiTransact opens one specified connection and associates it to one thread at a time. If the value of this attribute is thread, VisiTransact opens a connection per-work-thread when associating the given worker thread to a transaction.
xa-resource-alias
An <xa-resource-alias> element defines an alias name to a previously-defined <xa-resource> element:
<!ELEMENT xa-resource-alias
EMPTY
>
<!ATTLIST xa-resource-alias
name CDATA #REQUIRED
xa-resource CDATA #REQUIRED
>
name
The xa-resource’s alias name
xa-resource
The actual xa-resource that this alias points to.
When the name of an xa-resource-alias is referred to by a PMT <transaction> element’s xa-resource attribute, the actual xa-resource is used.
An example of XA resource descriptor
The following example shows a comprehensive description of an xa-resource-descriptor:
<?xml version="1.0"?>
<!DOCTYPE xa-resource-descriptor SYSTEM "xaresdesc.dtd">

<!-- an example of xa-resource-descriptor -->
<xa-resource-descriptor>

<!-- 1. list of xa resources -->
<xa-resource
name="oracle"
xa-switch="xaosw"
xa-conn-scope="thread"
<
<!- 2. list of xa connections -->
<xa-connection
info=
"Oracle_XA+Acc=P/scott/tiger+SesTm=10+SqlNet=ora92a+Threads=true"
/>
</xa-resource>

<!-- 3. list of resource alias(es) -->
<xa-resource-alias
name="default"
xa-resource="oracle"
/>

<xa-resource-alias
name="account-storage"
xa-resource="oracle"
/>

</xa-resource-descriptor>
In the previous example:
 The xa-resource specifies the xa-switch symbol xaosw, but not the xa-library file name. Therefore, VisiTransact resolves the xa switch within the current executable module, rather than from an external loaded library. This is a typical usage scenario because it is likely that the application has already linked with the client library of the database, which is likely to contain the needed XA API.
The xa-conn-scope is set to thread. This is consistent with the +Threads=true substring in the xa-connection’s info attribute. In this case, VisiTransact opens one dedicated XA connection per worker-thread when associating the thread with a transaction.
The xa-connection element omitted the name attribute, as well as the +DB=<name> substring in the info string. This is a typical usage scenario for an Oracle XA application under thread mode. The embedded SQL assumes the default connection. Applications do not need to use the AT clause.
An <xa-resource-alias> element is defined with the name default and points to the oracle <xa-resource> defined previously. Whenever a PMT <transaction> element is defined with the <xa-resource> name default, the referenced oracle xa-resource is used.
An additional <xa-resource-alias> element is defined with the name account-storage and points to the oracle <xa-resource> defined previously. Whenever a PMT <transaction> element is defined with the <xa-resource> name account-storage, the referenced oracle xa-resource is used.
VisiTransact properties
vbroker.its.its6xmode=< false|true>
If set to false, all VisiTransact PMT functions and optimizations are enabled. If set to true, PMT enhancements and optimizations are disabled, and the following deprecated features are enabled:
This property is available for performance comparison, bug isolation, and backward compatibility requirements. The default value is false.
vbroker.its.verbose=<false|true>
If set to true, VisiTransact prints low level exception and warning runtime information. The default value is false.
vbroker.its.xadesc=<xa-resource xml file name>
Specifies the XA-resource configuration file using this property. The default value is itsxadesc.xml.
RM recovery utility
The two-phase commit mechanism ensures that all nodes either commit or perform a rollback together. During the course of two-phase commit, if a failure occurs because of a network problem, database crash, or an unhandled software error, the transaction becomes in doubt and the resources in the database are locked and are not freed. To solve this problem VisiTransact comes with an RM recovery utility rmrecover (rmrecover.exe on Windows), along with automatic TM recovery.
Micro Focus recommends that you execute this utility for each Resource Manager involved in the transaction before restarting a VisiTransact application server that terminated in a failure.
The usage of rmrecover is:
% rmrecover <xa_resource_desc.xml> [<options>]
To run the rmrecover utility, complete the following steps:
1
2
For Windows: xa-library="oraclient9.dll"
For Unix: xa-library="libclntsh.so"
1
2
The RM recover utility contacts the database and fetches the list of transactions that are in doubt and either commits or rolls back each transaction.