⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndbtransaction.cpp

📁 mysql-5.0.22.tar.gz源码包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        theFirstOpInList = tRestOp;      else        theLastOpInList->next(tRestOp);      theLastOpInList = tLastOp;    }    assert(theFirstOpInList == NULL || tExecType == NoCommit);  } while (theFirstOpInList != NULL || tExecType != aTypeOfExec);  if (tCompletedFirstOp != NULL) {    tCompletedLastOp->next(theCompletedFirstOp);    theCompletedFirstOp = tCompletedFirstOp;    if (theCompletedLastOp == NULL)      theCompletedLastOp = tCompletedLastOp;  }#if ndb_api_count_completed_ops_after_blob_execute  { NdbOperation* tOp; unsigned n = 0;    for (tOp = theCompletedFirstOp; tOp != NULL; tOp = tOp->next()) n++;    ndbout << "completed ops: " << n << endl;  }#endif  if(savedError.code!=0 && theError.code==4350) // Trans already aborted      theError= savedError;  DBUG_RETURN(ret);}int NdbTransaction::executeNoBlobs(ExecType aTypeOfExec,                               AbortOption abortOption,                              int forceSend){  DBUG_ENTER("NdbTransaction::executeNoBlobs");  DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d", 		       aTypeOfExec, abortOption));//------------------------------------------------------------------------// We will start by preparing all operations in the transaction defined// since last execute or since beginning. If this works ok we will continue// by calling the poll with wait method. This method will return when// the NDB kernel has completed its task or when 10 seconds have passed.// The NdbTransactionCallBack-method will receive the return code of the// transaction. The normal methods of reading error codes still apply.//------------------------------------------------------------------------  Ndb* tNdb = theNdb;  Uint32 timeout = TransporterFacade::instance()->m_waitfor_timeout;  m_waitForReply = false;  executeAsynchPrepare(aTypeOfExec, NULL, NULL, abortOption);  if (m_waitForReply){    while (1) {      int noOfComp = tNdb->sendPollNdb(3 * timeout, 1, forceSend);      if (noOfComp == 0) {        /**          * This timeout situation can occur if NDB crashes.         */        ndbout << "This timeout should never occur, execute(..)" << endl;        setOperationErrorCodeAbort(4012);  // Error code for "Cluster Failure"        DBUG_RETURN(-1);      }//if      /*       * Check that the completed transactions include this one.  There       * could be another thread running asynchronously.  Even in pure       * async case rollback is done synchronously.       */      if (theListState != NotInList)        continue;#ifdef VM_TRACE      unsigned anyway = 0;      for (unsigned i = 0; i < theNdb->theNoOfPreparedTransactions; i++)        anyway += theNdb->thePreparedTransactionsArray[i] == this;      for (unsigned i = 0; i < theNdb->theNoOfSentTransactions; i++)        anyway += theNdb->theSentTransactionsArray[i] == this;      for (unsigned i = 0; i < theNdb->theNoOfCompletedTransactions; i++)        anyway += theNdb->theCompletedTransactionsArray[i] == this;      if (anyway) {        theNdb->printState("execute %x", this);        abort();      }#endif      if (theReturnStatus == ReturnFailure) {        DBUG_RETURN(-1);      }//if      break;    }  }  thePendingBlobOps = 0;  DBUG_RETURN(0);}//NdbTransaction::execute()/*****************************************************************************void executeAsynchPrepare(ExecType           aTypeOfExec,                          NdbAsynchCallback  callBack,                          void*              anyObject,                          CommitType         aTypeOfCommit);Return Value:  No return valueParameters :   aTypeOfExec:   Type of execute.               anyObject:     An object provided in the callback method               callBack:      The callback method               aTypeOfCommit: What to do when read/updated/deleted records                               are missing or inserted records already exist.Remark:        Prepare a part of a transaction in an asynchronous manner. *****************************************************************************/void NdbTransaction::executeAsynchPrepare( ExecType           aTypeOfExec,                                     NdbAsynchCallback  aCallback,                                     void*              anyObject,                                     AbortOption abortOption){  DBUG_ENTER("NdbTransaction::executeAsynchPrepare");  DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: %x, anyObject: %x", 		       aTypeOfExec, aCallback, anyObject));  /**   * Reset error.code on execute   */  if (theError.code != 0)    DBUG_PRINT("enter", ("Resetting error %d on execute", theError.code));  theError.code = 0;  NdbScanOperation* tcOp = m_theFirstScanOperation;  if (tcOp != 0){    // Execute any cursor operations    while (tcOp != NULL) {      int tReturnCode;      tReturnCode = tcOp->executeCursor(theDBnode);      if (tReturnCode == -1) {        DBUG_VOID_RETURN;      }//if      tcOp = (NdbScanOperation*)tcOp->next();    } // while    m_theLastScanOperation->next(m_firstExecutedScanOp);    m_firstExecutedScanOp = m_theFirstScanOperation;    // Discard cursor operations, since these are also    // in the complete operations list we do not need    // to release them.    m_theFirstScanOperation = m_theLastScanOperation = NULL;  }  bool tTransactionIsStarted = theTransactionIsStarted;  NdbOperation*	tLastOp = theLastOpInList;  Ndb* tNdb = theNdb;  CommitStatusType tCommitStatus = theCommitStatus;  Uint32 tnoOfPreparedTransactions = tNdb->theNoOfPreparedTransactions;  theReturnStatus     = ReturnSuccess;  theCallbackFunction = aCallback;  theCallbackObject   = anyObject;  m_abortOption   = abortOption;  m_waitForReply = true;  tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this;  theTransArrayIndex = tnoOfPreparedTransactions;  theListState = InPreparedList;  tNdb->theNoOfPreparedTransactions = tnoOfPreparedTransactions + 1;  if ((tCommitStatus != Started) ||      (aTypeOfExec == Rollback)) {/***************************************************************************** *	Rollback have been ordered on a started transaction. Call rollback. *      Could also be state problem or previous problem which leads to the  *      same action. ****************************************************************************/    if (aTypeOfExec == Rollback) {      if (theTransactionIsStarted == false || theSimpleState) {	theCommitStatus = Aborted;	theSendStatus = sendCompleted;      } else {	theSendStatus = sendABORT;      }    } else {      theSendStatus = sendABORTfail;    }//if    if (theCommitStatus == Aborted){      DBUG_PRINT("exit", ("theCommitStatus: Aborted"));      setErrorCode(4350);    }    DBUG_VOID_RETURN;  }//if  if (tTransactionIsStarted == true) {    if (tLastOp != NULL) {      if (aTypeOfExec == Commit) {/***************************************************************************** *	Set commit indicator on last operation when commit has been ordered *      and also a number of operations.******************************************************************************/        tLastOp->theCommitIndicator = 1;      }//if    } else {      if (aTypeOfExec == Commit && !theSimpleState) {	/**********************************************************************	 *   A Transaction have been started and no more operations exist. 	 *   We will use the commit method.	 *********************************************************************/        theSendStatus = sendCOMMITstate;	DBUG_VOID_RETURN;      } else {	/**********************************************************************	 * We need to put it into the array of completed transactions to 	 * ensure that we report the completion in a proper way. 	 * We cannot do this here since that would endanger the completed	 * transaction array since that is also updated from the receiver 	 * thread and thus we need to do it under mutex lock and thus we 	 * set the sendStatus to ensure that the send method will	 * put it into the completed array.	 **********************************************************************/        theSendStatus = sendCompleted;	DBUG_VOID_RETURN; // No Commit with no operations is OK      }//if    }//if  } else if (tTransactionIsStarted == false) {    NdbOperation* tFirstOp = theFirstOpInList;    if (tLastOp != NULL) {      tFirstOp->setStartIndicator();      if (aTypeOfExec == Commit) {        tLastOp->theCommitIndicator = 1;      }//if    } else {      /***********************************************************************       *    No operations are defined and we have not started yet.        *    Simply return OK. Set commit status if Commit.       ***********************************************************************/      if (aTypeOfExec == Commit) {        theCommitStatus = Committed;      }//if      /***********************************************************************       * We need to put it into the array of completed transactions to       * ensure that we report the completion in a proper way. We       * cannot do this here since that would endanger the completed       * transaction array since that is also updated from the       * receiver thread and thus we need to do it under mutex lock       * and thus we set the sendStatus to ensure that the send method       * will put it into the completed array.       ***********************************************************************/      theSendStatus = sendCompleted;      DBUG_VOID_RETURN;    }//if  }  NdbOperation* tOp = theFirstOpInList;  theCompletionStatus = NotCompleted;  while (tOp) {    int tReturnCode;    NdbOperation* tNextOp = tOp->next();    tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId);    if (tReturnCode == -1) {      theSendStatus = sendABORTfail;      DBUG_VOID_RETURN;    }//if    /*************************************************************************     * Now that we have successfully prepared the send of this operation we      * move it to the list of executing operations and remove it from the      * list of defined operations.     ************************************************************************/    tOp = tNextOp;  }   NdbOperation* tLastOpInList = theLastOpInList;  NdbOperation* tFirstOpInList = theFirstOpInList;  theFirstOpInList = NULL;  theLastOpInList = NULL;  theFirstExecOpInList = tFirstOpInList;  theLastExecOpInList = tLastOpInList;  theCompletionStatus = CompletedSuccess;  theNoOfOpSent		= 0;  theNoOfOpCompleted	= 0;  theSendStatus = sendOperations;  NdbNodeBitmask::clear(m_db_nodes);  NdbNodeBitmask::clear(m_failed_db_nodes);  DBUG_VOID_RETURN;}//NdbTransaction::executeAsynchPrepare()void NdbTransaction::close(){  theNdb->closeTransaction(this);}int NdbTransaction::refresh(){  return sendTC_HBREP();}/*****************************************************************************int sendTC_HBREP();Return Value:  No return value.  Parameters :   None.Remark:        Order NDB to refresh the timeout counter of the transaction. ******************************************************************************/int 	NdbTransaction::sendTC_HBREP()		// Send a TC_HBREP signal;{  NdbApiSignal* tSignal;  Ndb* tNdb = theNdb;  Uint32 tTransId1, tTransId2;  tSignal = tNdb->getSignal();  if (tSignal == NULL) {    return -1;  }  if (tSignal->setSignal(GSN_TC_HBREP) == -1) {    return -1;  }  TcHbRep * const tcHbRep = CAST_PTR(TcHbRep, tSignal->getDataPtrSend());    tcHbRep->apiConnectPtr = theTCConPtr;        tTransId1 = (Uint32) theTransactionId;  tTransId2 = (Uint32) (theTransactionId >> 32);  tcHbRep->transId1      = tTransId1;  tcHbRep->transId2      = tTransId2;   TransporterFacade *tp = TransporterFacade::instance();  tp->lock_mutex();   const int res = tp->sendSignal(tSignal,theDBnode);  tp->unlock_mutex();   tNdb->releaseSignal(tSignal);  if (res == -1){    return -1;  }        return 0;}//NdbTransaction::sendTC_HBREP()/*****************************************************************************int doSend();Return Value:  Return 0 : send was successful.               Return -1: In all other case.  Remark:        Send all operations belonging to this connection.               The caller of this method has the responsibility to remove the               object from the prepared transactions array on the Ndb-object.*****************************************************************************/intNdbTransaction::doSend(){  DBUG_ENTER("NdbTransaction::doSend");  /*  This method assumes that at least one operation have been defined. This  is ensured by the caller of this routine (=execute).  */  switch(theSendStatus){  case sendOperations: {    NdbOperation * tOp = theFirstExecOpInList;    do {      NdbOperation* tNextOp = tOp->next();      const Uint32 lastFlag = ((tNextOp == NULL) ? 1 : 0);      const int tReturnCode = tOp->doSend(theDBnode, lastFlag);      if (tReturnCode == -1) {        theReturnStatus = ReturnFailure;        break;      }//if      tOp = tNextOp;    } while (tOp != NULL);    Ndb* tNdb = theNdb;    theSendStatus = sendTC_OP;    theTransactionIsStarted = true;    tNdb->insert_sent_list(this);    DBUG_RETURN(0);  }//case  case sendABORT:  case sendABORTfail:{  /***********************************************************************   * Rollback have been ordered on a not started transaction.    * Simply return OK and set abort status.   ***********************************************************************/    if (theSendStatus == sendABORTfail) {      theReturnStatus = ReturnFailure;    }//if    if (sendROLLBACK() == 0) {      DBUG_RETURN(0);    }//if    break;  }//case  case sendCOMMITstate:    if (sendCOMMIT() == 0) {      DBUG_RETURN(0);    }//if    break;  case sendCompleted:    theNdb->insert_completed_list(this); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -