This section focuses on using the Current interface in VisiTransact-managed transactions. It includes information about how to gain access to a VisiTransact-managed transaction with Current, and begin, rollback, and commit the transaction using the methods in the Current interface. It also explains how transactional objects can share in a VisiTransact-managed transaction.
CORBA::Object_var
obj = orb->resolve_initial_references("TransactionCurrent");
CosTransactions::Current_var
current = CosTransactions::Current::_narrow(obj);
// To use OMG behavior on CosTransactions methods and also use the
// additional VisiTransact methods
CORBA::Object_var
obj = orb->resolve_initial_references("TransactionCurrent");
VISTransactions::Current_var
current = VISTransactions::Current::_narrow(obj);
// get object reference to my object implementation
MyBank_var bank = MyBank::_bind();
// start a transaction
current->begin();
if(bank->withdraw(10, 444))
{
// invoke a CORBA request
current->commit(0);
}
else
{
current->rollback();
}
...If you have a process and want to use multiple threads in the same transaction, you must pass the transaction context to each of the threads. In the typical scenario, you will start with a thread that has the transaction context—either because it is the originator and invoked Current::begin(), or because an operation passed the transaction context to it (implicitly or explicitly) and it needs to propagate that context to the other threads. This can be achieved by making the transaction's Control object available to the other threads and they can invoke Current::resume() specifying that Control object. Note that VisiTransact cannot provide checked behavior in this case.You can manage multiple transactions within a thread; however, a thread can have only one active transaction at a time. The suspend() method is used to disassociate the current context, and resume() is used to associate another context. The table in “Working with the Current interface and its methods” describes the methods used to implement multiple transactions within a thread.The following example shows an example of an object that originates multiple transactions from within a thread. This example illustrates that the MyBank_impl::withdraw() method can suspend the transaction in which the method was called, start a new transaction, and then resume the earlier transaction.CORBA::Boolean MyBank_impl::withdraw( CORBA::Long accountNo,
CORBA::Float amount)
{
try
{
// check to see if a transaction has been started
CORBA::Object_var
obj = orb->resolve_initial_references("TransactionCurrent");
CosTransactions::Current_var
current = CosTransactions::Current::_narrow(obj);
// Suspend the current transaction. If there is no current transaction,
// the control will be null.
CosTransactions::Control_var control = current->suspend();
// start a new transaction
try
{
current->begin();
// do your logic
current->commit(0);
}
catch(...)
{
// resume earlier transaction
current->resume(control);
throw;
}
}
catch(..) { }
}By default, the first time you start a transaction with begin() an instance of the VisiTransact Transaction Service is found using the Smart Agent. For details on the Smart Agent, see the VisiBroker Developer's Guide.You can control the instance of the VisiTransact Transaction Service used with arguments passed to ORB_init(), or by how you set the VISTransactions::Current interface arguments. The Current arguments will override any arguments passed to ORB_init(). The arguments will only take effect for subsequent transactions that use Current::begin().
CORBA::Float amount)
{
// get ORB instance
CORBA::ORB_ptr orb = CORBA::ORB_init();
// get Current reference
CORBA::Object_var
obj = orb->resolve_initial_references("TransactionCurrent");
CosTransactions::Current_var
current = CosTransactions::Current::_narrow(obj);
CORBA::Boolean startFlag = 0;//use to signal creation of the transaction
CORBA::Boolean status = 0;
try
{
// check to see if a transaction has been started
if(current->get_status() == CosTransactions::StatusNoTransaction)
{
current->begin();
startFlag = 1; //we started and now own the current transaction
}
if(balance(accountNo) > amount)
{
// withdraw logic
...
status = 1;
}
}
catch(...) { }
if(startFlag && status)
{
current->commit();
}
else if(startFlag)
{
current->rollback();
}
return status;
}When using Current, only an originator can terminate the transaction with commit() or rollback(). In this case, if a participant does not want the transaction to commit, it can use the rollback_only() method from the Current interface. When the rollback_only() method is called by a participant, the transaction associated with the target object is modified so that the only possible outcome is to rollback the transaction.When invoking rollback_only(), the CosTransactions::NoTransaction exception is raised if there is no transaction in progress. The following example shows how a participant would use the rollback_only() method....
CosTransactions::Current_var current;
current->rollback_only();
...A participant can obtain information about the current transaction such as its transaction name or transaction status using methods in the Current interface. The following table discusses these methods.