1 /* ====== BEGIN INCLUDE FILE            mrds_start_transaction.incl.pl1 =========================== */
  2 
  3 
  4 
  5 /****^  HISTORY COMMENTS:
  6   1) change(85-11-17,Dupuis), approve(85-12-16,MCR7314),
  7      audit(86-02-04,Brunelle), install(86-02-05,MR12.0-1013):
  8      This entry is being made to cover the changes made on 85-05-06 and
  9      85-04-19 by Thanh Nguyen. The dependency on dbcb.user_started_transaction
 10      was removed because not all modules need the dbcb, and the
 11      user_transaction_id field was added for mrds_dsl_retrieve (mrds error
 12      list #136).
 13                                                    END HISTORY COMMENTS */
 14 
 15 
 16 /*
 17                     BEGIN_DESCRIPTION
 18 
 19    A generalized routine accessed by all MRDS modules (with the temporary
 20    (perhaps) exception of restructuring modules) that must start transactions
 21    if none are present.  The intent is that it be executed as inline code.
 22    The variable mstxn_transactions_needed must be set prior to entering this
 23    code.  In most cases a simple assignment from dbcb_data.transactions_needed
 24    will suffice.  Included are procedures called mstxn_cleanup and
 25    mstxn_any_other.  These procedures must be called by cleanup and any_other
 26    handlers in the program.  Such handlers should be established just prior to
 27    the inclusion of this code and disabled just following the inclusion of
 28    mrds_finish_transaction.  Directly prior to establishing the handlers
 29    mstxn_txn_id must be set to "0"b.  This must be done even though this
 30    include file does the same, because this code might not have been entered
 31    yet when the handler is invoked.  Directly following this include file the
 32    contents of mstxn_code should be examined.  If zero, then either the
 33    transaction was successfully started or no transaction was required.  If the
 34    mrds_finish_transaction code is referenced in general error handling
 35    situations where the possibility exists that the code in this include file
 36    has not been executed, it is necessary to initialize mstxn_txn_id to "0"b at
 37    the beginning of the program.
 38 
 39                     END_DESCRIPTION
 40 
 41    Written 82-09-28 by Paul W. Benjamin.
 42    Modified 82-12-09 by PWB to include mstxn_any_other.
 43    Modified 83-01-07 by PWB to not reference the dbcb.
 44    Modified 83-01-10 by PWB to add a call to continue_to_signal_ to the
 45                      any_other handler in situations where the module did
 46                      not start the transaction.
 47    Modified 83-05-05 by PWB to abandon when abort fails.
 48    Modified 83-05-18 by PWB to use mstxn_temp_code in calls to abandon and
 49                      and abort.
 50    Modified 83-05-19 by PWB to handle transaction_deadlock and
 51                      transaction_bj_full conditions.
 52    Modified 84-02-04 by PWB to add trailing underscores to the 2 conditions
 53                      and to handle transaction_lock_timeout_.
 54    Modified 85-04-14 by Thanh Nguyen: Added code to set the
 55                      dbcb.user_started_transaction flag.
 56    Modified 85-04-19 by Thanh Nguyen to add user_started_transaction flag.
 57    Modified 85-05-06 By Thanh Nguyen to synchronize this include file in the
 58                      directory >ldd>include and >exl>mrd>i
 59 */
 60 
 61 dcl continue_to_signal_ entry (fixed bin(35));
 62 dcl dm_error_$no_current_transaction fixed bin (35) ext static;
 63 dcl error_table_$null_info_ptr fixed bin(35) ext static;
 64 dcl find_condition_info_ entry (ptr, ptr, fixed bin(35));
 65 dcl mstxn_code fixed bin (35);
 66 dcl mstxn_retries fixed;
 67 dcl mstxn_temp_code fixed bin (35);
 68 dcl mstxn_transactions_needed bit (1) aligned;
 69 dcl user_started_transaction bit (1) aligned;
 70 dcl mstxn_txn_id bit (36) aligned;
 71 dcl user_transaction_id bit (36) aligned;
 72 dcl transaction_manager_$abandon_txn entry (bit (36) aligned, fixed bin (35));
 73 dcl transaction_manager_$abort_txn entry (bit (36) aligned, fixed bin (35));
 74 dcl transaction_manager_$begin_txn entry (fixed bin, fixed bin (35), bit (36) aligned, fixed bin (35));
 75 dcl transaction_manager_$get_current_txn_id entry (bit (36) aligned, fixed bin (35));
 76 dcl transaction_manager_$handle_conditions entry ();
 77 dcl 1 mstxn_condition_info like condition_info;
 78 %page;
 79 %include dm_tm_modes;
 80 %skip;
 81 %include condition_info;
 82 %page;
 83           mstxn_code = 0;
 84           mstxn_txn_id = "0"b;
 85 
 86           if ^mstxn_transactions_needed                     /* only need transactions */
 87                then goto mstxn_exit;                        /* for protected page files */
 88           mstxn_retries = 0;
 89           call transaction_manager_$get_current_txn_id (mstxn_txn_id, mstxn_code);
 90           if mstxn_code ^= dm_error_$no_current_transaction /* and if none already in progress */
 91                then do;
 92                user_started_transaction = "1"b;
 93                user_transaction_id = mstxn_txn_id;          /* better save it for mrds_dsl_retrieve */
 94                mstxn_txn_id = "0"b;                         /* you didn't start it, it's none of your business */
 95                goto mstxn_exit;
 96           end;
 97 
 98           user_started_transaction = "0"b;
 99           call transaction_manager_$begin_txn (TM_NORMAL_MODE, 0, mstxn_txn_id, mstxn_code);
100           user_transaction_id = mstxn_txn_id;          /* better save it for mrds_dsl_retrieve */
101 
102 mstxn_cleanup:
103 proc;
104 
105 /*  This procedure MUST be called by a cleanup handler. */
106 
107           if mstxn_txn_id ^= "0"b
108           then do;
109                call transaction_manager_$abort_txn (mstxn_txn_id, mstxn_temp_code);
110                if mstxn_temp_code ^= 0
111                     then call transaction_manager_$abandon_txn (mstxn_txn_id, mstxn_temp_code);
112           end;
113 
114      end mstxn_cleanup;
115 
116 mstxn_any_other:
117 proc;
118 
119 /*  This procedure MUST be called by an any_other handler. */
120 
121           if mstxn_txn_id ^= "0"b
122           then do;
123                call find_condition_info_ (null (), addr(mstxn_condition_info), mstxn_temp_code);
124                if mstxn_condition_info.condition_name = "transaction_deadlock_"
125                     then do;
126                     mftxn_code = dm_error_$lock_deadlock;
127                     goto mftxn_check_code;
128                end;
129                else if mstxn_condition_info.condition_name = "transaction_bj_full_"
130                     | mstxn_condition_info.condition_name = "transaction_lock_timeout_"
131                     then do;
132                     mftxn_code = dm_error_$bj_journal_full;
133                     goto mftxn_check_code;
134                end;
135                else call transaction_manager_$handle_conditions;
136           end;
137           else call continue_to_signal_ (mstxn_code);       /* code returned will always be zero */
138      end mstxn_any_other;
139 
140 mstxn_exit:
141 
142 /* ------ END INCLUDE FILE              mrds_start_transaction.incl.pl1 --------------------------- */