83 lines
3.1 KiB
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;
|
|
}
|