INT32 rtnCoord2PhaseCommit::doPhase1( MsgHeader *pMsg,
                                         pmdEDUCB *cb,
                                         INT64 &contextID,
                                         rtnContextBuf *buf )
   {
      INT32 rc = SDB_OK;
      CHAR *pMsgReq                    = NULL;

      rc = buildPhase1Msg( (CHAR*)pMsg, &pMsgReq );
      PD_RC_CHECK( rc, PDERROR,
                   "Failed to build the message on phase1(rc=%d)",
                   rc );

      // execute on data nodes
      rc = executeOnDataGroup( (MsgHeader*)pMsgReq, cb, contextID, buf ) ;
      PD_RC_CHECK( rc, PDERROR,
                   "Failed to execute on data-group on phase1(rc=%d)",
                   rc ) ;

   done:
      if ( pMsgReq )
      {
         SDB_OSS_FREE( pMsgReq );
         pMsgReq = NULL;
      }
      return rc;
   error:
      goto done;
   }
   INT32 rtnCoord2PhaseCommit::doPhase2( CHAR * pReceiveBuffer, SINT32 packSize,
                                         CHAR * * ppResultBuffer, pmdEDUCB * cb,
                                         MsgOpReply & replyHeader )
   {
      INT32 rc = SDB_OK;
      pmdKRCB *pKrcb                   = pmdGetKRCB();
      CoordCB *pCoordcb                = pKrcb->getCoordCB();
      netMultiRouteAgent *pRouteAgent  = pCoordcb->getRouteAgent();
      CHAR *pMsgReq                    = NULL;
      MsgHeader *pMsgHead              = NULL;
      CoordGroupList groupLst;
      CoordGroupList sendGroupLst;

      rc = buildPhase2Msg( pReceiveBuffer, &pMsgReq );
      PD_RC_CHECK( rc, PDERROR,
                  "failed to build the message on phase1(rc=%d)",
                  rc );

      pMsgHead = (MsgHeader *)pMsgReq;
      pMsgHead->TID = cb->getTID();

      rc = executeOnDataGroup( pMsgReq, pRouteAgent, cb );
      PD_RC_CHECK( rc, PDERROR,
                  "failed to execute on data-group on phase1(rc=%d)",
                  rc );
   done:
      if ( pMsgReq )
      {
         SDB_OSS_FREE( pMsgReq );
         pMsgReq = NULL;
      }
      return rc;
   error:
      goto done;
   }
   INT32 rtnCoordTransRollback::execute( CHAR * pReceiveBuffer, SINT32 packSize,
                                         CHAR * * ppResultBuffer, pmdEDUCB * cb,
                                         MsgOpReply & replyHeader,
                                         BSONObj **ppErrorObj )
   {
      INT32 rc                         = SDB_OK;
      CHAR *pMsgReq                    = NULL;
      MsgHeader *pMsgHead              = NULL;
      INT32 bufferSize                 = 0;
      pmdKRCB *pKrcb                   = pmdGetKRCB();
      CoordCB *pCoordcb                = pKrcb->getCoordCB();
      netMultiRouteAgent *pRouteAgent  = pCoordcb->getRouteAgent();
      MsgHeader *pHeader               = (MsgHeader *)pReceiveBuffer;
      replyHeader.header.messageLength = sizeof( MsgOpReply );
      replyHeader.header.opCode        = MSG_BS_TRANS_ROLLBACK_RSP;
      replyHeader.header.routeID.value = 0;
      replyHeader.contextID            = -1;
      replyHeader.flags                = SDB_OK;
      replyHeader.numReturned          = 0;
      replyHeader.startFrom            = 0;

      if ( pHeader )
      {
         replyHeader.header.requestID     = pHeader->requestID;
         replyHeader.header.TID           = pHeader->TID;
      }

      if ( !cb->isTransaction() )
      {
         rc = SDB_DPS_TRANS_NO_TRANS;
         goto error;
      }

      cb->startRollback();

      rc = msgBuildTransRollbackMsg( &pMsgReq, &bufferSize );
      PD_RC_CHECK( rc, PDERROR,
                  "failed to build the message(rc=%d)",
                  rc );

      pMsgHead = (MsgHeader *)pMsgReq;
      pMsgHead->TID = cb->getTID();
      rc = executeOnDataGroup( pMsgReq, pRouteAgent, cb );
      cb->delTransaction();
      PD_RC_CHECK( rc, PDERROR,
                  "failed to rollback(rc=%d)",
                  rc );
   done:
      if ( pMsgReq )
      {
         SDB_OSS_FREE( pMsgReq );
      }
      cb->stopRollback();
      return rc;
   error:
      replyHeader.flags = rc;
      goto done;
   }