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

📄 bank.cpp

📁 mysql-5.0.22.tar.gz源码包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* Copyright (C) 2003 MySQL AB   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; either version 2 of the License, or   (at your option) any later version.   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "Bank.hpp"#include <time.h>#include <NdbSleep.h>#include <UtilTransactions.hpp>Bank::Bank(Ndb_cluster_connection& con, bool _init):  m_ndb(&con, "BANK"),  m_maxAccount(-1),  m_initialized(false){  if(_init)    init();}int Bank::init(){  if (m_initialized == true)    return NDBT_OK;  myRandom48Init(NdbTick_CurrentMillisecond());  m_ndb.init();     if (m_ndb.waitUntilReady(30) != 0)  {    ndbout << "Ndb not ready" << endl;    return NDBT_FAILED;  }    if (getNumAccounts() != NDBT_OK)    return NDBT_FAILED;  m_initialized = true;  return NDBT_OK;}int Bank::performTransactions(int maxSleepBetweenTrans, int yield){  int transactions = 0;  while(performTransaction() == NDBT_OK)  {    transactions++;        if (maxSleepBetweenTrans > 0){      int val = myRandom48(maxSleepBetweenTrans);      NdbSleep_MilliSleep(val);          }        if((transactions % 100) == 0)      g_info << transactions  << endl;        if (yield != 0 && transactions >= yield)      return NDBT_OK;  }  return NDBT_FAILED;}int Bank::performTransaction(){  int result = NDBT_OK;  if (m_maxAccount <= 0){    g_err << "No accounts in bank" << endl;    return NDBT_FAILED;  }  int fromAccount = myRandom48(m_maxAccount);  int toAccount = myRandom48(m_maxAccount);      if (fromAccount == toAccount){    // Increase toAccount with 1    toAccount = (toAccount+1)%m_maxAccount;  }      int maxAmount = getMaxAmount();      int amount = myRandom48(maxAmount);retry_transaction:  int res = performTransaction(fromAccount, toAccount, amount);  if (res != 0){    switch (res){    case NDBT_FAILED:      g_err << "performTransaction returned NDBT_FAILED" << endl	    << "  fromAccount = " << fromAccount << endl	    << "  toAccount = " << toAccount << endl	    << "  amount = " << amount << endl;      result = NDBT_FAILED;      break;    case NOT_ENOUGH_FUNDS:      //   ndbout << "performTransaction returned NOT_ENOUGH_FUNDS" << endl;	      break;    case NDBT_TEMPORARY:      g_err << "TEMPORARY_ERRROR retrying" << endl;      goto retry_transaction;      break;    default:      g_info << "performTransaction returned "<<res << endl;	      break;    }  }  return result;}/** * Perform a transaction in the bank.  * Ie. transfer money from one account to another. * * @param  * @return 0 if successful or an error code */int Bank::performTransaction(int fromAccountId,			     int toAccountId,			     int amount ){  /**   * 1. Start transaction   * 2. Check balance on from account, if there is   *    not enough funds abort transaction   * 3. Update ACCOUNT set balance = balance - amount on   *    from account    * 4. Insert withdrawal in TRANSACTION   * 5. Insert deposit in transaction   * 6. Update ACCOUNT set balance = balance + amount on    *    to account   * 7. Commit transaction   */   //  g_info << "performTransaction " << fromAccountId   //	 << ", "<<toAccountId<<", "<<amount << endl;  // Call the first implementation of this trans  // In the future we can have several different versions of this trans  // and call them randomly   return performTransactionImpl1(fromAccountId, toAccountId, amount); }int Bank::performTransactionImpl1(int fromAccountId,				  int toAccountId,				  int amount ){  int check;      // Ok, all clear to do the transaction  Uint64 transId;  int result = NDBT_OK;  if ((result= getNextTransactionId(transId)) != NDBT_OK){    return result;  }  NdbConnection* pTrans = m_ndb.startTransaction();  if( pTrans == NULL ) {    const NdbError err = m_ndb.getNdbError();    if (err.status == NdbError::TemporaryError){      ERR(err);      return NDBT_TEMPORARY;    }    ERR(err);    return NDBT_FAILED;  }      Uint64 currTime;  if (prepareGetCurrTimeOp(pTrans, currTime) != NDBT_OK){    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  /**    * Check balance on from account   */  NdbOperation* pOp = pTrans->getNdbOperation("ACCOUNT");  if (pOp == NULL) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp->readTupleExclusive();  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp->equal("ACCOUNT_ID", fromAccountId);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      NdbRecAttr* balanceFromRec = pOp->getValue("BALANCE");  if( balanceFromRec ==NULL ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      NdbRecAttr* fromAccountTypeRec = pOp->getValue("ACCOUNT_TYPE");  if( fromAccountTypeRec == NULL ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  /**    * Read balance on to account   */  NdbOperation* pOp6 = pTrans->getNdbOperation("ACCOUNT");  if (pOp6 == NULL) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp6->readTupleExclusive();  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp6->equal("ACCOUNT_ID", toAccountId);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      NdbRecAttr* balanceToRec = pOp6->getValue("BALANCE");  if( balanceToRec == NULL ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  NdbRecAttr* toAccountTypeRec = pOp6->getValue("ACCOUNT_TYPE");  if( toAccountTypeRec == NULL ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pTrans->execute(NoCommit);  if( check == -1 ) {    const NdbError err = pTrans->getNdbError();    m_ndb.closeTransaction(pTrans);        if (err.status == NdbError::TemporaryError){      ERR(err);      return NDBT_TEMPORARY;    }    ERR(err);    return NDBT_FAILED;  }      Uint32  balanceFrom = balanceFromRec->u_32_value();  //  ndbout << "balanceFrom: " << balanceFrom << endl;  if (((Int64)balanceFrom - amount) < 0){    m_ndb.closeTransaction(pTrans);          //ndbout << "Not enough funds" << endl;          return NOT_ENOUGH_FUNDS;  }  Uint32 fromAccountType = fromAccountTypeRec->u_32_value();  Uint32  balanceTo = balanceToRec->u_32_value();  //  ndbout << "balanceTo: " << balanceTo << endl;  Uint32 toAccountType = toAccountTypeRec->u_32_value();  /**   * Update balance on from account   */  NdbOperation* pOp2 = pTrans->getNdbOperation("ACCOUNT");  if (pOp2 == NULL) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp2->updateTuple();  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp2->equal("ACCOUNT_ID", fromAccountId);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp2->setValue("BALANCE", balanceFrom - amount);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  /**   * Update balance on to account   */  NdbOperation* pOp3 = pTrans->getNdbOperation("ACCOUNT");  if (pOp3 == NULL) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp3->updateTuple();  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp3->equal("ACCOUNT_ID", toAccountId);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp3->setValue("BALANCE", balanceTo + amount);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  /**   * Insert withdrawal transaction   */  NdbOperation* pOp4 = pTrans->getNdbOperation("TRANSACTION");  if (pOp4 == NULL) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp4->insertTuple();  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp4->equal("TRANSACTION_ID", transId);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp4->equal("ACCOUNT", fromAccountId);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp4->setValue("ACCOUNT_TYPE", fromAccountType);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp4->setValue("OTHER_ACCOUNT", toAccountId);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp4->setValue("TRANSACTION_TYPE", WithDrawal);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp4->setValue("TIME", currTime);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp4->setValue("AMOUNT", amount);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  /**   * Insert deposit transaction   */  NdbOperation* pOp5 = pTrans->getNdbOperation("TRANSACTION");  if (pOp5 == NULL) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp5->insertTuple();  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }      check = pOp5->equal("TRANSACTION_ID", transId);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp5->equal("ACCOUNT", toAccountId);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp5->setValue("ACCOUNT_TYPE", toAccountType);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp5->setValue("OTHER_ACCOUNT", fromAccountId);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp5->setValue("TRANSACTION_TYPE", Deposit);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp5->setValue("TIME", currTime);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pOp5->setValue("AMOUNT", amount);  if( check == -1 ) {    ERR(pTrans->getNdbError());    m_ndb.closeTransaction(pTrans);    return NDBT_FAILED;  }  check = pTrans->execute(Commit);  if( check == -1 ) {    const NdbError err = pTrans->getNdbError();    m_ndb.closeTransaction(pTrans);        if (err.status == NdbError::TemporaryError){      ERR(err);      return NDBT_TEMPORARY;    }    ERR(err);    return NDBT_FAILED;  }      m_ndb.closeTransaction(pTrans);        return NDBT_OK;  }    int Bank::performMakeGLs(int yield){  int result;    int counter, maxCounter;  int yieldCounter = 0;  while (1){    // Counters to keep tracck of how many    // GLs should be made before performing a validation    counter = 0;    maxCounter = 50 + myRandom48(100);        /**      * Validate GLs and Transactions for previous days     *     */    result = performValidateGLs();    if (result != NDBT_OK){      if (result == VERIFICATION_FAILED){	g_err << "performValidateGLs verification failed" << endl;	return NDBT_FAILED;      }      g_info << "performValidateGLs failed" << endl;      return NDBT_FAILED;      continue;    }    result = performValidatePurged();    if (result != NDBT_OK){      if (result == VERIFICATION_FAILED){	g_err << "performValidatePurged verification failed" << endl;	return NDBT_FAILED;      }      g_info << "performValidatePurged failed" << endl;      return NDBT_FAILED;    }    while (1){      yieldCounter++;      if (yield != 0 && yieldCounter >= yield)	return NDBT_OK;      /**       * Find last GL time.         * ( GL record with highest time value)       */      Uint64 lastGLTime;      if (findLastGL(lastGLTime) != NDBT_OK){		g_info << "findLastGL failed" << endl;	// Break out of inner while loop	break;      }            lastGLTime++;            /**        * If last GL time + 1 is smaller than current time       * perform a GL for that time       */      Uint64 currTime;      if (getCurrTime(currTime) != NDBT_OK){	g_info << "getCurrTime failed" << endl;	// Break out of inner while loop	break;      }            if (lastGLTime < currTime){	counter++;	if (performMakeGL(lastGLTime) != NDBT_OK){	  g_info << "performMakeGL failed" << endl;	// Break out of inner while loop	  break;	}		if (counter > maxCounter){	  // Break out of inner while loop and 	  // validatePreviousGLs	  g_info << "counter("<<counter<<") > maxCounter("<<maxCounter<<")" << endl;	  break;	}      } else {	;//ndbout << "It's not time to make GL yet" << endl;	// ndbout << "Sleeping 1 second" << endl;	NdbSleep_SecSleep(1);            }            Uint32 age = 3;      if (purgeOldGLTransactions(currTime, age) != NDBT_OK){        g_info << "purgeOldGLTransactions failed" << endl;	// Break out of inner while loop	break;      }                     }  }      return NDBT_FAILED;  }int Bank::performValidateAllGLs(){  int result;    while (1){        /**      * Validate GLs and Transactions for previous days     * Set age so that ALL GL's are validated     */    int age = 100000;    result = performValidateGLs(age);    if (result != NDBT_OK){      if (result == VERIFICATION_FAILED){

⌨️ 快捷键说明

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