Global transactions in ODBC programs

A global transaction is a recoverable unit of work, or transaction, that is made up of changes to a collection of resources. You include global transactions in your application to access multiple recoverable resources in the context of a single transaction.

Global transactions enable you to write applications that participate in two-phase commit processing. All resources that participate in a global transaction are guaranteed to be committed or rolled back as an atomic unit. z/OS® Transaction Management and Resource Recovery Services (RRS) coordinate the updates that occur within a global transaction by using a two-phase commit protocol.

To enable global transactions, specify the keywords AUTOCOMMIT=0, MULTICONTEXT=0, and MVSATTACHTYPE=RRSAF in the initialization file.

To use global transactions, perform the following actions, which include RRS APIs, in your application:
  1. Call ATRSENV() to provide environmental settings for RRS before you allocate connection handles.
  2. Call ATRBEG() to mark the beginning of the global transaction.
  3. Update the resources that are part of the global transaction.
  4. Call SRRCMIT(), SRRBACK(), or the RRS service ATREND() to mark the end of the global transaction.
  5. Repeat steps 2 and 4 for each global transaction that you include in your application.

SQLEndTran() is disabled within each global transaction, but you can still use this function to commit or rollback local transactions that are outside of the boundaries of the global transactions.

DB2® ODBC does not support global transaction processing for applications that run under a stored procedure.

The following example shows an application that uses global transaction processing. This application uses both ODBC and RRS APIs to make global transactions on two resources.
Figure 1. An application that performs ODBC global transactions
/* Provide environmental settings for RRS        */
ATRSENV();                                                                                            
/* Get an environment handle (henv)              */
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);                                                                               
/* Get a connection handle (hdbc1)               */
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);                  
/* Get a connection handle (hdbc2)               */
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc2);
/* Start a global transaction                    */  
ATRBEG( ... , ATR_GLOBAL_MODE , ... );                                                                    
/* Connect to STLEC1                             */  
SQLConnect( hdbc1, "STLEC1", ... );    
/* Execute some SQL with hdbc1                   */  
SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);                     
SQLExecDirect( hstmt1, ... );                        
SQLExecDirect( hstmt1, ... );                        
  .                                                 
  .                                           
/* Connect to STLEC1B                            */  
SQLConnect( hdbc2, "STLEC1B", ... );      
/* Execute some SQL with hdbc2                   */ 
SQLAllocHandle(SQL_HANDLE_STMT, hdbc2, &hstmt2);                    
SQLExecDirect( hstmt2, ... );                       
SQLExecDirect( hstmt2, ... );                       
   .                                                
   .             
/*  Free statement handles                       */ 
SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);                    
SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);              
/*  Commit global transaction                    */ 
SRRCMIT();                                          
/*  Start a global transaction                   */ 
ATRBEG( ... , ATR_GLOBAL_MODE , ... );     
/*  Execute some SQL with hdbc1                  */ 
SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);                    
SQLExecDirect( hstmt1, ... );                       
SQLExecDirect( hstmt1, ... );                       
   .                                                
   .                                                
/*  Execute some SQL with hdbc2                  */ 
SQLAllocHandle(SQL_HANDLE_STMT, hdbc2, &hstmt2);                    
SQLExecDirect( hstmt2, ... );                       
SQLExecDirect( hstmt2, ... );                       
   .                                                
   .                                                
/*  Commit global transaction                    */ 
ATREND( ATR_COMMIT_ACTION );       
/*  Disconnect hdbc1 and hdbc2                   */ 
SQLDisconnect( hdbc1 );                             
SQLDisconnect( hdbc2 );