fis-gtm/sr_port/op_trestart.c

83 lines
3.1 KiB
C

/****************************************************************
* *
* Copyright 2001, 2010 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gdsroot.h"
#include "gdsblk.h"
#include "gdskill.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "gdscc.h"
#include "buddy_list.h" /* needed for tp.h */
#include "cdb_sc.h"
#include "jnl.h"
#include "hashtab_int4.h" /* needed for tp.h */
#include "tp.h"
#include "tp_restart.h"
#include "op.h"
GBLREF unsigned char t_fail_hist[CDB_MAX_TRIES];
GBLREF unsigned int t_tries;
GBLREF trans_num tstart_local_tn; /* copy of global variable "local_tn" at op_tstart time */
GBLREF uint4 dollar_tlevel;
/* Sets t_fail_hist[t_tries] to cdb_sc_optrestart to indicate an explicit TP restart was requested by the user. Before doing
* so, it checks if we are in the final retry and issues another error if the explicit restart is requested more than once.
*/
void op_trestart_set_cdb_code(void)
{
static trans_num trestart_final_retry_local_tn;
static uint4 trestart_final_retry_cnt;
error_def(ERR_TRESTMAX);
/* Since this function can be called from the TRESTART and ZMESSAGE (with msgid=ERR_TPRETRY) commands, it is not
* necessary we are in TP at this point. If so, tp_restart will signal the appropriate error so skip the final
* retry TP check if we are not in TP. This is necessary because the use of tstart_local_tn assumes we are in TP.
*/
if (dollar_tlevel && (CDB_STAGNATE == t_tries))
{ /* If we are in the final retry and holding crit (if this TP transaction has opened at least one database
* at this point), we want to limit the # of times the user can restart this transaction as a TP restart
* entails wasted work all while holding crit on the db and preventing others from accessing the same.
*/
if (trestart_final_retry_local_tn != tstart_local_tn)
{
trestart_final_retry_cnt = 0; /* Restart counting */
trestart_final_retry_local_tn = tstart_local_tn;
}
trestart_final_retry_cnt++;
assert(MAX_TP_FINAL_RETRY_TRESTART_CNT >= trestart_final_retry_cnt);
if (MAX_TP_FINAL_RETRY_TRESTART_CNT <= trestart_final_retry_cnt)
{ /* Currently TRESTMAX message text is framed based on the assumption that we do
* not allow more than one TRESTART in the final retry. If this ever changes (by
* changing the macro MAX_TP_FINAL_RETRY_TRESTART_CNT), we need to change the
* message text. The assert below is a reminder for this case.
*/
assert(1 == (MAX_TP_FINAL_RETRY_TRESTART_CNT - 1));
rts_error(VARLSTCNT(1) ERR_TRESTMAX);
}
}
t_fail_hist[t_tries] = cdb_sc_optrestart;
}
void op_trestart(int newlevel)
{
error_def(ERR_TPRETRY);
op_trestart_set_cdb_code();
assert(1 == newlevel); /* newlevel probably needs to become GBLREF assigned here and reset to 1 in tp_restart */
INVOKE_RESTART;
}