VisiTransact Guide : Determining your approach to transactions

Determining your approach to transactions
This section provides an overview of the directions you can take when building transactional applications with VisiTransact Transaction Manager.
Transaction management approaches
A program can choose the type of context management it will use, and the method of context propagation used to transmit the transactional context to other objects. Using a type of context management does not restrict your choice of transaction propagation.
Direct vs. indirect context management
The CORBAservices Transaction Service specification from OMG defines the following types of context management:
Indirect Context Management. With indirect context management, an application uses the Current object provided by the Transaction Service to associate the transaction context with the application thread of control and manage it.
Direct Context Management. In direct context management, an application manipulates the Control and other objects associated with the transaction.
Using indirect context management simplifies programming, and enables your application to take advantage of performance enhancements and optimizations that are possible when the VisiTransact Transaction Service controls the transaction context. For example, VisiTransact-managed transactions take advantage of the underlying VisiBroker ORB to minimize remote calls. Further, VisiTransact-managed transactions save system resources by caching the propagation context and transaction context at the application end, thereby eliminating unnecessary remote calls to retrieve this data.
Direct context management might be more convenient if you are using explicit propagation or you are trying to use multiple VisiTransact Transaction Service instances to originate transactions. In addition, if you do not want to link in VisiTransact libraries, you must use direct context management. In rare circumstances you may want to use your own stubs from your own IDL files rather than use VisiTransact libraries. The only way you can use your own stubs is by using direct context management. If you use indirect context management, you use Current; when you use Current, you use VisiTransact libraries.
If you use direct context management, or a mixture of both context management modes, you must ensure transactional integrity for your application. Once you use direct context management, the VisiTransact Transaction Service has lost the ability to check transaction completeness. See “How does the VisiTransact Transaction Service ensure checked behavior?” for more information about checked behavior.
Implicit vs. explicit propagation
The CORBAservices Transaction Service specification from OMG defines the following propagation types:
Implicit propagation. With implicit propagation, requests are implicitly associated with the application's transaction—meaning they share the application's transaction context. The transaction context is transmitted implicitly to the participating objects by the VisiTransact Transaction Service, without direct intervention by the transaction originator. An object that supports implicit propagation would not typically expect to receive any Transaction Service object as an explicit parameter.
Explicit propagation. With explicit propagation, the transaction originator (and potentially participating transactional objects) propagates a transaction context by passing objects defined by the Transaction Service as explicit parameters.
The major advantage to implicit propagation is that the VisiTransact Transaction Service handles transaction propagation for you. Another advantage is that implicit propagation does not require you to change the signatures of existing methods to support transactions—by making the object transactional, you enable all of the object's methods to be executed as part of a transaction.
Explicit propagation also has its advantages. First, it allows you to mix transactional and non-transactional methods within an object. This is useful if you want to have transactional semantics for one method but not for others in a transaction.
Secondly, you might use explicit propagation is if you require interoperability with CORBA 1.x implementations (such as VisiBroker 2.0). Because explicit propagation does not require cooperation between the ORB and the Transaction Service, it can be used for this kind of backward-compatibility.
A third reason for using explicit propagation is that it allows other objects to terminate transactions. In other words, explicit propagation enables you to pass the Terminator to another transaction participant; this enables the participant to terminate the transaction.
Context management and propagation
A client may use either direct or indirect context management with either implicit or explicit propagation. This results in several ways in which client applications may communicate with transactional objects:
Indirect context management with implicit propagation
The client application uses methods on the Current object to create and control its transactions. When it issues requests on transactional objects, the transaction context associated with the current thread is implicitly propagated to the object.
VisiTransact-managed transactions fall into this category. With VisiTransact-managed transactions, VisiTransact guarantees checked behavior. For more information about checked behavior, see “How does the VisiTransact Transaction Service ensure checked behavior?”.
Note
Indirect context management with implicit propagation is not exactly the same as VisiTransact-managed transactions. VisiTransact-managed transactions specifically dictate the use of Current::begin followed by implicit propagation.
See “Creating and propagating VisiTransact-managed transactions” for details on using VisiTransact-managed transactions.
Indirect context management with explicit propagation
The client uses a combination of the Current, Control, and other objects which describe the state of the transaction. A client application that uses the Current object (and therefore, is also automatically using implicit propagation) can use explicit propagation by gaining access to the Control object with the Current::getControl() method. It can use a VisiTransact Transaction Service object as an explicit parameter to a transactional object. This is explicit propagation.
Direct context management with implicit propagation
The client uses a combination of the Current, Control, and other objects which describe the state of the transaction. A client that accesses the VisiTransact Transaction Service objects directly can use the Current::resume() method to set the implicit transaction context associated with its thread. This allows the client to invoke methods of objects that require implicit propagation of the transaction context.
Direct context management with explicit propagation
The client application directly accesses the Control object and the other objects which describe the state of the transaction. To propagate the transaction to an object, the client must include the appropriate VisiTransact Transaction Service object as an explicit parameter of a method.
See “Other methods of creating and propagating transactions” for details on managing transactions from your application.
In-process vs. out-of-process VisiTransact transaction service
If most of your transactions are isolated to, and used within, a single process, you may decide to use an in-process instance of the VisiTransact Transaction Service. However, this means that the requirements for transactions (that is, high availability)—usually handled by a stand-alone instance of the VisiTransact Transaction Service—can only be met if the application process remains running when transactions are in progress. This requirement is especially important if other applications (outside of the process) are using the instance of the VisiTransact Transaction Service that you have embedded within your application process. See “Embedding a VisiTransact Transaction Service instance in your application”.
You can use multiple instances of the VisiTransact Transaction Service on your network. To make the behavior of your transactions more predictable, you can specify which instance of the VisiTransact Transaction Service your transaction originator will use.
You can control the instance of the VisiTransact Transaction Service used by arguments passed to ORB_init() or by how you set the Current interface attributes. The Current attributes will override any arguments passed to ORB_init(). This will only take effect for subsequent transactions using Current::begin().
See “Discovering an instance of the VisiTransact Transaction service” for an explanation of how to set the -Dvbroker.ots.currentName argument.
Multithreading
VisiTransact is multithreaded. Multithreaded applications benefit from the features of the underlying VisiBroker ORB including its thread pooling and connection management capabilities.
Although the thread and connection management of the VisiBroker ORB can conserve system resources, the thread pooling strategy could be a disadvantage if you need control over which thread is assigned to a particular transaction. With the thread pooling model, a worker thread is assigned for each client request, but only for the duration of that particular request. Consider other threading models offered by VisiBroker if you need more control. Also note that thread safety issues may arise if other libraries are not thread safe.
Integrating existing applications and transactional systems
You can integrate several external transactional systems using other CORBA Transaction Services. Since VisiTransact is fully CORBA 2.6-compliant, it is interoperable with other CORBA 2.6-compliant implementations of the OMG CORBA Transaction Service specification. VisiTransact provides valuable extensions to the CORBAservices specification (useful methods such as begin_with_name(), and other features) that cannot be handled by other transaction service implementations.
In addition, you can use any CORBAservices-compliant resource provided by yourself, a third-party, or a database vendor.
Another option is to implement your own Resource using the Resource interface. This option requires complex programming because logging and recovery, heuristics, and other necessary coding is not handled for you.
Using a combination of approaches
You can mix and match any of the approaches described in this chapter to suit the purposes of your distributed, transactional application.
Mixing various types of transaction approaches. For example, you might have a transaction using explicit propagation and then switch to implicit. See “Changing from explicit propagation to implicit” for more information.
Integrating multiple systems with your VisiTransact application. For example, you can use databases, transaction processing monitors, and messaging software in your transactional application—and integrate them all with VisiTransact.
Implementing transactions for the web
If you are developing a web-based transactional application, you may decide to use web browsers as a front-end to the application, and leave the transaction origination and other logic to a server-based object.
Keeping the VisiTransact transaction within the boundaries of the Web server's local network means that you gain performance advantages because of the locality of the VisiTransact Transaction Service and the transaction participants. Also, you provide local autonomy of transactions within one company's control. With this application architecture, communication problems across external networks will not affect transaction completion or integrity.
Building C++ VisiTransact applications
When designing C++ applications that use VisiTransact you can use standalone instances of the VisiTransact Transaction Service, or embed instances of the VisiTransact Transaction Service in your C++ application components.
The following sections describe these alternatives in greater detail.
Using stand-alone VisiTransact Transaction Service instances
Most VisiTransact applications will use an instance of the VisiTransact Transaction Service that is running on the network—rather than embedding an instance in their process. When the application is executed it can use any available VisiTransact Transaction Service instance, or control the instance of the VisiTransact Transaction Service that is used.
A C++ program that uses the VisiTransact Transaction Service interfaces must be linked with its_support.lib (its_support.so on Solaris).
Note
If the program only uses direct context management with explicit propagation, it can use the stubs and header files generated from the CosTransactions.idl or VISTransactions.idl files.
Embedding a VisiTransact Transaction Service instance in your application
Embedding a VisiTransact Transaction Service instance in a C++ executable entails linking in ots_r.lib (ots_r.so on Solaris) and its_support.lib (its_support.so on Solaris) libraries with your application. Adding these libraries to the link line embeds an instance of the VisiTransact Transaction Service in the application's process.
If you link with VisiTransact libraries, you must include the _c.hh and _s.hh files provided by VisiTransact. You cannot generate your own stub files. This is to ensure you are using versions of the headers that are compatible with the objects embedded in VisiTransact libraries. You must perform this step if you link with the VisiTransact libraries.
Additionally, you must explicitly initialize and terminate the instance of the VisiTransact Transaction Service from your application as described in the following steps:
1
Include visits.h in your C++ application.
2
Initialize the VisiTransact server components with ORB_init(). Invoke VISTransactionService::init() to initialize the VisiTransact Transaction Service instance. This must happen after the ORB_init() invocation. For example:
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
VISIts::init(argc, argv);
3
Invoke VISTransactionService::terminate() to shutdown the VisiTransact Transaction Service instance.
4
UNIX:ots_r.so
WinNT:ots_r.lib
Note
ots64_r.so and its_support64.so on 64 bit platform. ots_r.a(ots64_r.a) and its_support.a(its_support64.a) on AIX and ots_r.sl(ots64_r.sl) and its_support.sl(its_support64.sl) on HP-UX.
5
The example below shows an application that embeds the VisiTransact Transaction Service.
// Application main
#include <visits.h> // for VISIts
#include <corba.h>

int main(int argc, char** argv)
{
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
VISTransactionService::init(argc, argv);
// the main work of the application is now performed
...
VISTransactionService::terminate();
}
Binding to the embedded instance of the VisiTransact Transaction Service
When you have the VisiTransact Transaction Service embedded in the application server, you must make sure that the client binds to the correct instance of the VisiTransact Transaction Service. To do so, you must specify the name of the VisiTransact Transaction Service when starting the client application using certain command-line arguments. This name must match the one that is embedded in the application server.
Note
If you are creating transactions directly from the TransactionFactory rather than using Current, then the client will have to bind to the correct TransactionFactory. Refer to the semantics for binding to any CORBA object to make sure the client binds to the correct object.
Using header files supplied with VisiTransact
To compile a C++ source file that will link with its_support.lib or ots_r.lib, you must include the version of CosTransactions_c.hh or VISTransactions_c.hh supplied by VisiTransact, not an IDL client stub header file that you generate from CosTransactions.idl or VISTransactions.idl. (The objects you will link against in the VisiTransact-supplied libraries are valid only against the header files used to build them.) Any application using the Current interface will be linking against these libraries.