mariadb/storage/innobase/api/api0misc.cc
2016-12-30 08:56:13 +02:00

132 lines
3.5 KiB
C++

/*****************************************************************************
Copyright (c) 2008, 2015, Oracle and/or its affiliates. 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 api/api0misc.cc
InnoDB Native API
2008-08-01 Created by Sunny Bains
3/20/2011 Jimmy Yang extracted from Embedded InnoDB
*******************************************************/
#include "ha_prototypes.h"
#include "api0misc.h"
#include "trx0roll.h"
#include "srv0srv.h"
#include "dict0mem.h"
#include "dict0dict.h"
#include "pars0pars.h"
#include "row0sel.h"
#include "lock0lock.h"
/*********************************************************************//**
Sets a lock on a table.
@return error code or DB_SUCCESS */
dberr_t
ib_trx_lock_table_with_retry(
/*=========================*/
trx_t* trx, /*!< in/out: transaction */
dict_table_t* table, /*!< in: table to lock */
enum lock_mode mode) /*!< in: LOCK_X or LOCK_S */
{
trx->op_info = "setting table lock";
return(lock_table_for_trx(table, trx, mode));
}
/****************************************************************//**
Handles user errors and lock waits detected by the database engine.
@return TRUE if it was a lock wait and we should continue running
the query thread */
ibool
ib_handle_errors(
/*=============*/
dberr_t* new_err,/*!< out: possible new error encountered in
lock wait, or if no new error, the value
of trx->error_state at the entry of this
function */
trx_t* trx, /*!< in: transaction */
que_thr_t* thr, /*!< in: query thread */
trx_savept_t* savept) /*!< in: savepoint or NULL */
{
dberr_t err;
handle_new_error:
err = trx->error_state;
ut_a(err != DB_SUCCESS);
trx->error_state = DB_SUCCESS;
switch (err) {
case DB_LOCK_WAIT_TIMEOUT:
trx_rollback_for_mysql(trx);
break;
/* fall through */
case DB_DUPLICATE_KEY:
case DB_FOREIGN_DUPLICATE_KEY:
case DB_TOO_BIG_RECORD:
case DB_ROW_IS_REFERENCED:
case DB_NO_REFERENCED_ROW:
case DB_CANNOT_ADD_CONSTRAINT:
case DB_TOO_MANY_CONCURRENT_TRXS:
case DB_OUT_OF_FILE_SPACE:
if (savept) {
/* Roll back the latest, possibly incomplete
insertion or update */
trx_rollback_to_savepoint(trx, savept);
}
break;
case DB_LOCK_WAIT:
lock_wait_suspend_thread(thr);
if (trx->error_state != DB_SUCCESS) {
que_thr_stop_for_mysql(thr);
goto handle_new_error;
}
*new_err = err;
return(TRUE); /* Operation needs to be retried. */
case DB_DEADLOCK:
case DB_LOCK_TABLE_FULL:
/* Roll back the whole transaction; this resolution was added
to version 3.23.43 */
trx_rollback_for_mysql(trx);
break;
case DB_CORRUPTION:
case DB_FOREIGN_EXCEED_MAX_CASCADE:
break;
default:
ut_error;
}
if (trx->error_state != DB_SUCCESS) {
*new_err = trx->error_state;
} else {
*new_err = err;
}
trx->error_state = DB_SUCCESS;
return(FALSE);
}