mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 05:52:27 +01:00
f1b80d8ef1
trx_state_eq(): Add the parameter bool relaxed=false, to allow trx->state==TRX_STATE_NOT_STARTED where a different state is expected, if an error has been reported. trx_release_savepoint_for_mysql(): Pass relaxed=true to trx_state_eq(). That is, allow the transaction to be idle when ROLLBACK TO SAVEPOINT is attempted after an error has been reported to the client.
184 lines
5.2 KiB
Text
184 lines
5.2 KiB
Text
/*****************************************************************************
|
|
|
|
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
|
|
Copyright (c) 2016, MariaDB Corporation. All Rights Reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/**************************************************//**
|
|
@file include/trx0trx.ic
|
|
The transaction
|
|
|
|
Created 3/26/1996 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
/**********************************************************************//**
|
|
Determines if a transaction is in the given state.
|
|
The caller must hold trx_sys->mutex, or it must be the thread
|
|
that is serving a running transaction.
|
|
A running transaction must be in trx_sys->ro_trx_list or trx_sys->rw_trx_list
|
|
unless it is a non-locking autocommit read only transaction, which is only
|
|
in trx_sys->mysql_trx_list.
|
|
@return TRUE if trx->state == state */
|
|
UNIV_INLINE
|
|
ibool
|
|
trx_state_eq(
|
|
/*=========*/
|
|
const trx_t* trx, /*!< in: transaction */
|
|
trx_state_t state, /*!< in: state;
|
|
if state != TRX_STATE_NOT_STARTED
|
|
asserts that
|
|
trx->state != TRX_STATE_NOT_STARTED */
|
|
bool relaxed)
|
|
/*!< in: whether to allow
|
|
trx->state == TRX_STATE_NOT_STARTED
|
|
after an error has been reported */
|
|
{
|
|
#ifdef UNIV_DEBUG
|
|
switch (trx->state) {
|
|
case TRX_STATE_PREPARED:
|
|
ut_ad(!trx_is_autocommit_non_locking(trx));
|
|
return(trx->state == state);
|
|
|
|
case TRX_STATE_ACTIVE:
|
|
assert_trx_nonlocking_or_in_list(trx);
|
|
return(state == trx->state);
|
|
|
|
case TRX_STATE_COMMITTED_IN_MEMORY:
|
|
assert_trx_in_list(trx);
|
|
return(state == trx->state);
|
|
|
|
case TRX_STATE_NOT_STARTED:
|
|
/* This state is not allowed for running transactions. */
|
|
ut_a(state == TRX_STATE_NOT_STARTED
|
|
|| (relaxed
|
|
&& thd_get_error_number(trx->mysql_thd)));
|
|
ut_ad(!trx->in_rw_trx_list);
|
|
ut_ad(!trx->in_ro_trx_list);
|
|
return(state == trx->state);
|
|
}
|
|
ut_error;
|
|
#endif /* UNIV_DEBUG */
|
|
return(trx->state == state);
|
|
}
|
|
|
|
/****************************************************************//**
|
|
Retrieves the error_info field from a trx.
|
|
@return the error info */
|
|
UNIV_INLINE
|
|
const dict_index_t*
|
|
trx_get_error_info(
|
|
/*===============*/
|
|
const trx_t* trx) /*!< in: trx object */
|
|
{
|
|
return(trx->error_info);
|
|
}
|
|
|
|
/*******************************************************************//**
|
|
Retrieves transaction's que state in a human readable string. The string
|
|
should not be free()'d or modified.
|
|
@return string in the data segment */
|
|
UNIV_INLINE
|
|
const char*
|
|
trx_get_que_state_str(
|
|
/*==================*/
|
|
const trx_t* trx) /*!< in: transaction */
|
|
{
|
|
/* be sure to adjust TRX_QUE_STATE_STR_MAX_LEN if you change this */
|
|
switch (trx->lock.que_state) {
|
|
case TRX_QUE_RUNNING:
|
|
return("RUNNING");
|
|
case TRX_QUE_LOCK_WAIT:
|
|
return("LOCK WAIT");
|
|
case TRX_QUE_ROLLING_BACK:
|
|
return("ROLLING BACK");
|
|
case TRX_QUE_COMMITTING:
|
|
return("COMMITTING");
|
|
default:
|
|
return("UNKNOWN");
|
|
}
|
|
}
|
|
|
|
/**********************************************************************//**
|
|
Determine if a transaction is a dictionary operation.
|
|
@return dictionary operation mode */
|
|
UNIV_INLINE
|
|
enum trx_dict_op_t
|
|
trx_get_dict_operation(
|
|
/*===================*/
|
|
const trx_t* trx) /*!< in: transaction */
|
|
{
|
|
trx_dict_op_t op = static_cast<trx_dict_op_t>(trx->dict_operation);
|
|
|
|
#ifdef UNIV_DEBUG
|
|
switch (op) {
|
|
case TRX_DICT_OP_NONE:
|
|
case TRX_DICT_OP_TABLE:
|
|
case TRX_DICT_OP_INDEX:
|
|
return(op);
|
|
}
|
|
ut_error;
|
|
#endif /* UNIV_DEBUG */
|
|
return(op);
|
|
}
|
|
/**********************************************************************//**
|
|
Flag a transaction a dictionary operation. */
|
|
UNIV_INLINE
|
|
void
|
|
trx_set_dict_operation(
|
|
/*===================*/
|
|
trx_t* trx, /*!< in/out: transaction */
|
|
enum trx_dict_op_t op) /*!< in: operation, not
|
|
TRX_DICT_OP_NONE */
|
|
{
|
|
#ifdef UNIV_DEBUG
|
|
enum trx_dict_op_t old_op = trx_get_dict_operation(trx);
|
|
|
|
switch (op) {
|
|
case TRX_DICT_OP_NONE:
|
|
ut_error;
|
|
break;
|
|
case TRX_DICT_OP_TABLE:
|
|
switch (old_op) {
|
|
case TRX_DICT_OP_NONE:
|
|
case TRX_DICT_OP_INDEX:
|
|
case TRX_DICT_OP_TABLE:
|
|
goto ok;
|
|
}
|
|
ut_error;
|
|
break;
|
|
case TRX_DICT_OP_INDEX:
|
|
ut_ad(old_op == TRX_DICT_OP_NONE);
|
|
break;
|
|
}
|
|
ok:
|
|
#endif /* UNIV_DEBUG */
|
|
|
|
trx->ddl = true;
|
|
trx->dict_operation = op;
|
|
}
|
|
|
|
/********************************************************************//**
|
|
In XtraDB it is impossible for a transaction to own a search latch outside of
|
|
InnoDB code, so there is nothing to release on demand. We keep this function to
|
|
simplify maintenance.*/
|
|
UNIV_INLINE
|
|
void
|
|
trx_search_latch_release_if_reserved(
|
|
/*=================================*/
|
|
trx_t* trx MY_ATTRIBUTE((unused))) /*!< in: transaction */
|
|
{
|
|
ut_ad(!trx->has_search_latch);
|
|
}
|