blob: 6fc1526396bf5989e1d4587208e45c7e0a781363 [file] [log] [blame]
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
#ifndef EX_TRANSACTION_H
#define EX_TRANSACTION_H
/* -*-C++-*-
*****************************************************************************
*
* File: ex_transaction.h
* Description: TCB/TDB for transaction-related SQL statements
* and ExTransaction object that represents a TMF transaction
*
* Created: 7/10/95
* Language: C++
*
*
*
*
*****************************************************************************
*/
// -----------------------------------------------------------------------
#include "ex_stdh.h"
#include "ComTdb.h"
#include "ex_tcb.h"
#include "ex_error.h"
#include "Int64.h"
struct TmfPhandle_Struct {
short Data[10];
};
class CliGlobals;
class ExTransaction : public NABasicObject
{
public:
ExTransaction(CliGlobals * cliGlob, CollHeap *heap);
virtual ~ExTransaction();
//////////////////////////////////////////////////////////////
// Methods to perform transaction related operations.
// Used for explicit (called by application via cli calls)
// and implicit (called internally when a statement requires
// a transaction and one is not already running) transaction
// operations.
//////////////////////////////////////////////////////////////
short beginTransaction();
short suspendTransaction();
short resumeTransaction();
//////////////////////////////////////////////////////////////
// RollbackStatement ALWAYS rollbacks Xn. Used unless stmt
// atomicity support is in.
// RollbackTransaction
// only rollbacks if executor started the Xn.
//////////////////////////////////////////////////////////////
short rollbackStatement();
short rollbackTransaction(NABoolean isWaited = FALSE);
short rollbackTransactionWaited();
short doomTransaction();
short waitForRollbackCompletion(Int64 transid);
void cleanupTransaction();
short commitTransaction(NABoolean waited = FALSE);
short waitForCommitCompletion(Int64 transid);
short inheritTransaction();
short validateTransaction();
short setProcessTransToContextTrans
(TmfPhandle_Struct * oldProcessTransId, /* out */
NABoolean & processTransactionChanged /* out */);
short resetProcessTrans(TmfPhandle_Struct * oldProcessTransId);
NABoolean xnInProgress() { return xnInProgress_; }
TransMode * getTransMode() { return transMode_; }
TransMode * getUserTransMode();
TransMode * getTransModeNext(){ return &transModeNext_; }
short setTransMode(TransMode * trans_mode);
// Soln 10-050210-4624
/* This method retrieves from TMF and returns the TCBREF associated with the
* currently active transaction. If the optional parameters, transId and
* txHandle, are supplied, the transaction identifier and handle also are
* returned.
*/
short getCurrentXnId(Int64 *tcbref,
Int64 *transId = 0, short *txHandle = NULL);
short getCurrentTxHandle(short * txHandle);
// this method returns the current Xn Id as known to executor.
Int64 getExeXnId() { return exeXnId_; }
// Soln 10-050210-4624
// This method returns the id of the current transaction.
Int64 getTransid() { return transid_;}
// this method returns the current savepoint id, if dp2 savepoint is
// being used for this stmt. -1, if they are not.
Int64 getSavepointId() { return savepointId_; }
// this method generates a savepoint id. Its a juliantimestamp, for now.
// If a transaction is not in progress, no savepoint id is generated.
void generateSavepointId();
NABoolean exeStartedXn() { return exeStartedXn_; }
NABoolean exeStartedXnDuringRecursiveCLICall()
{ return exeStartedXnDuringRecursiveCLICall_; }
NABoolean &implicitXn() { return implicitXn_; }
NABoolean userEndedExeXn() { return userEndedExeXn_; }
void setTransId(Int64 transid);
void disableAutoCommit();
void enableAutoCommit();
// returns TRUE, if auto commit is on. Otherwise, returns FALSE.
NABoolean autoCommit()
{
if ((transMode_) &&
(transMode_->autoCommit() == TransMode::ON_))
return TRUE;
else
return FALSE;
}
// returns TRUE, if multi commit is on. Otherwise, returns FALSE.
NABoolean multiCommit()
{
if ((transMode_) &&
(transMode_->multiCommit() == TransMode::MC_ON_))
return TRUE;
else
return FALSE;
}
ComDiagsArea *getDiagsArea() {return transDiagsArea_;}
inline CliGlobals *getCliGlobals() { return cliGlob_;}
void updateROVal(Int16 roval)
{
roVal_ = roval;
}
Int16 getROVal() { return roVal_;}
void updateRBVal(Int16 rbval)
{
rbVal_ = rbval;
}
Int16 getRBVal() { return rbVal_;}
void updateAIVal(Int32 aival)
{
aiVal_ = aival;
}
Int32 getAIVal() { return aiVal_;}
void setMayAlterDb(NABoolean x)
{
mayAlterDb_ = x;
}
NABoolean mayAlterDb() { return mayAlterDb_; }
void setMayHoldLock(NABoolean x)
{
mayHoldLock_ = x;
}
NABoolean mayHoldLock() { return mayHoldLock_; }
void setDp2Xns(NABoolean x)
{
dp2Xns_ = x;
}
NABoolean dp2Xns() { return dp2Xns_; }
void resetXnState();
private:
// pointer to executor globals. Used to get to the open
// cursor list. This list is needed to close all open
// cursors at commit/rollback time.
CliGlobals * cliGlob_;
// transaction attributes
TransMode * transMode_;
// user transaction attributes that may be different to default trans mode
TransMode * userTransMode_;
TransMode transModeNext_; // mode to use AFTER this trans completes
// (see ComTdbControl.cpp)
// Diagnostics Area for the transaction operation.
// The transaction methods such as beginTransaction()... can be
// called by the cli directly. This member is provided to
// hold the diagnostics for such callers, who's request
// are not sent thro' the conventional down queues.
ComDiagsArea *transDiagsArea_;
ComCondition* errorCond_;
CollHeap* heap_;
short local_or_encompassing_trans;
// if a transaction is/was in progress from executor's point of view.
// This may not be the current transaction.
NABoolean xnInProgress_;
// TRUE, if executor started the transaction.
NABoolean exeStartedXn_;
// The next flag is set if the executor started this transaction
// during a recursive call (e.g. a metadata lookup or resource
// fork read during fixup). Such implicitly started transactions
// must be committed before returning from the top-level CLI
// call, otherwise data integrity problems could result in
// multi-context applications.
NABoolean exeStartedXnDuringRecursiveCLICall_;
// TRUE, if executor started the transaction implicitely.
// FALSE, if the app started Xn by calling CLI or by starting
// it in the application.
NABoolean implicitXn_;
// set to TRUE, if user application ended (committed/aborted/started)
// an executor started Xn (xnInProgress_ is TRUE).
// According to ANSI, only a SQL agent that started the XN can
// end it.
// Exe will stay in this state until user application 'ends' the
// transaction by calling SQL commit/rollback.
NABoolean userEndedExeXn_;
// transaction id as known to executor, if a Xn is running.
// Otherwise, set to -1.
Int64 exeXnId_;
// Soln 10-050210-4624
// The actual transaction id as known to the executor. Note that exeXnId_ is
// actually the TCBREF associated with the transaction. exeXnId_ will be used
// in all the messaging with DP2, MXCMP and MXESP.
// This field will be used for interacting with TMF.
Int64 transid_;
Int64 savepointId_;
TmfPhandle_Struct exeTxHandle_;
// set to TRUE, if the autoCommit mode was temporarily
// disabled because a BEGIN WORK statement was issued.
NABoolean autoCommitDisabled_;
// If a volatile schema already exists when this transaction is started,
// remember that.
// if a volatile schema was created after this transaction was started,
// and this transaction is aborted, then this flag is used to reset the
// volatile schema state in executor and mxcmp.
NABoolean volatileSchemaExists_;
// Creates the diagsArea for the caller. This also sets
// the optional integer and optional string for the diagnostics
// area.
void createDiagsArea(Int32 error, Int32 retCode, const char *string);
Int16 roVal_;
Int16 rbVal_;
Int32 aiVal_;
// Two flags that help track whether a transaction can be suspended.
NABoolean mayAlterDb_;
NABoolean mayHoldLock_;
// if set to TRUE, then dp2 transactions are allowed. DP2 transactions
// are currently allowed for single row unique queries which are being
// executed in auto commit mode. It could be either implicit autocommit
// where exe commits the Xn at the end, or explicit autocommit mode where
// the app commits the Xn after each stmt.
// If they are allowed, then their use is determined in PartitionAccess
// operator based on other conditions.
NABoolean dp2Xns_;
int transtag_;
};
///////////////////////////////////////////////////////
// class ExTransTdb
///////////////////////////////////////////////////////
#include "ComTdbTransaction.h"
// -----------------------------------------------------------------------
// Classes defined in this file
// -----------------------------------------------------------------------
class ExTransTdb;
// -----------------------------------------------------------------------
// Classes referenced in this file
// -----------------------------------------------------------------------
class ex_tcb;
// -----------------------------------------------------------------------
// ExTransTdb
// -----------------------------------------------------------------------
class ExTransTdb : public ComTdbTransaction
{
public:
// ---------------------------------------------------------------------
// Constructor is only called to instantiate an object used for
// retrieval of the virtual table function pointer of the class while
// unpacking. An empty constructor is enough.
// ---------------------------------------------------------------------
ExTransTdb()
{}
virtual ~ExTransTdb()
{}
// ---------------------------------------------------------------------
// Build a TCB for this TDB. Redefined in the Executor project.
// ---------------------------------------------------------------------
virtual ex_tcb *build(ex_globals *globals);
private:
// ---------------------------------------------------------------------
// !!!!!!! IMPORTANT -- NO DATA MEMBERS ALLOWED IN EXECUTOR TDB !!!!!!!!
// *********************************************************************
// The Executor TDB's are only used for the sole purpose of providing a
// way to supplement the Compiler TDB's (in comexe) with methods whose
// implementation depends on Executor objects. This is done so as to
// decouple the Compiler from linking in Executor objects unnecessarily.
//
// When a Compiler generated TDB arrives at the Executor, the same data
// image is "cast" as an Executor TDB after unpacking. Therefore, it is
// a requirement that a Compiler TDB has the same object layout as its
// corresponding Executor TDB. As a result of this, all Executor TDB's
// must have absolutely NO data members, but only member functions. So,
// if you reach here with an intention to add data members to a TDB, ask
// yourself two questions:
//
// 1. Are those data members Compiler-generated?
// If yes, put them in the ComTdbTransaction instead.
// If no, they should probably belong to someplace else (like TCB).
//
// 2. Are the classes those data members belong defined in the executor
// project?
// If your answer to both questions is yes, you might need to move
// the classes to the comexe project.
// ---------------------------------------------------------------------
};
//
// Task control block
//
class ExTransTcb : public ex_tcb
{
friend class ExTransTdb;
friend class ExTransPrivateState;
public:
enum Step
{
EMPTY_,
PROCESSING_,
DONE_,
CANCELLED_
};
ExTransTcb(const ExTransTdb & trans_tdb,
ex_globals * glob = 0);
~ExTransTcb();
virtual short work();
ex_queue_pair getParentQueue() const{return qparent_;};
inline Int32 orderedQueueProtocol() const{return ((const ExTransTdb &)tdb).orderedQueueProtocol();}
void freeResources(){};
Int32 numChildren() const { return 0; }
const ex_tcb* getChild(Int32 /*pos*/) const { return 0; }
private:
ex_queue_pair qparent_;
atp_struct *workAtp_;
inline ExTransTdb & transTdb() const{return (ExTransTdb &) tdb;};
inline ex_expr * diagAreaSizeExpr() const
{ return transTdb().diagAreaSizeExpr_; };
// if diagsArea is not NULL, then its error code is used.
// Otherwise, err is used to handle error.
void handleErrors(ex_queue_entry *pentry_down,
ComDiagsArea* diagsArea,
ExeErrorCode err = EXE_INTERNAL_ERROR);
};
class ExTransPrivateState : public ex_tcb_private_state
{
friend class ExTransTcb;
public:
ExTransPrivateState(const ExTransTcb * tcb); //constructor
~ExTransPrivateState(); // destructor
ex_tcb_private_state * allocate_new(const ex_tcb * tcb);
private:
ExTransTcb::Step step_;
};
#endif