Ejemplo n.º 1
0
  /**
   * Dedupe initiate task messages. Check if the initiate task message is seen before.
   *
   * @param inTxnId The txnId of the message
   * @param in The initiate task message
   * @return A client response to return if it's a duplicate, otherwise null.
   */
  public InitiateResponseMessage dedupe(long inTxnId, TransactionInfoBaseMessage in) {
    if (in instanceof Iv2InitiateTaskMessage) {
      final Iv2InitiateTaskMessage init = (Iv2InitiateTaskMessage) in;
      final StoredProcedureInvocation invocation = init.getStoredProcedureInvocation();
      final String procName = invocation.getProcName();

      /*
       * Ning - @LoadSinglepartTable and @LoadMultipartTable always have the same txnId
       * which is the txnId of the snapshot.
       */
      if (!(procName.equalsIgnoreCase("@LoadSinglepartitionTable")
              || procName.equalsIgnoreCase("@LoadMultipartitionTable"))
          && inTxnId <= m_lastSeenTxnId) {
        // already sequenced
        final InitiateResponseMessage resp = new InitiateResponseMessage(init);
        resp.setResults(
            new ClientResponseImpl(
                ClientResponseImpl.UNEXPECTED_FAILURE,
                new VoltTable[0],
                ClientResponseImpl.IGNORED_TRANSACTION));
        return resp;
      }
    }
    return null;
  }
  public MultiPartitionParticipantTxnState(
      Mailbox mbox, ExecutionSite site, TransactionInfoBaseMessage notice) {
    super(mbox, site, notice);
    m_hsId = site.getSiteId();
    m_nonCoordinatingSites = null;
    m_isCoordinator = false;
    m_context = site.m_context;

    // Check to make sure we are the coordinator, it is possible to get an intiate task
    // where we aren't the coordinator because we are a replica of the coordinator.
    if (notice instanceof InitiateTaskMessage) {
      // keep this around for DR purposes
      m_invocation = ((InitiateTaskMessage) notice).getStoredProcedureInvocation();

      // Determine if mismatched results are okay.
      if (m_invocation != null) {
        String procName = m_invocation.getProcName();
        if (procName.startsWith("@AdHoc")) {
          // For now the best we can do with ad hoc is to always allow mismatched results.
          // We don't know if it's non-deterministic or not. But the main use case for
          // being lenient is "SELECT * FROM TABLE LIMIT n", typically run as ad hoc.
          m_allowMismatchedResults = true;
        } else {
          // Walk through the statements to see if any are non-deterministic.
          if (m_context != null && m_context.procedures != null) {
            Procedure proc = m_context.procedures.get(procName);
            if (proc != null) {
              CatalogMap<Statement> stmts = proc.getStatements();
              if (stmts != null) {
                for (Statement stmt : stmts) {
                  if (!stmt.getIscontentdeterministic() || !stmt.getIsorderdeterministic()) {
                    m_allowMismatchedResults = true;
                    break;
                  }
                }
              }
            }
          }
        }
      }

      if (notice.getCoordinatorHSId() == m_hsId) {
        m_isCoordinator = true;
        m_task = (InitiateTaskMessage) notice;
        m_durabilityFlag = m_task.getDurabilityFlagIfItExists();
        SiteTracker tracker = site.getSiteTracker();
        m_readyWorkUnits.add(
            new WorkUnit(tracker, m_task, null, m_hsId, null, false, m_allowMismatchedResults));

        /*
         * ENG-3374: Use the same set of non-coordinator sites the
         * initiator sent out the participant notices to, so that when
         * the coordinator send out the fragment works all participants
         * will get them.
         *
         * During rejoin, the initiator's site tracker and the
         * coordinator's site tracker may not be consistent for a brief
         * period of time. So can't rely on the site tracker to tell the
         * coordinator which sites to send work to.
         */
        m_nonCoordinatingSites = m_task.getNonCoordinatorSites();
      } else {
        m_durabilityFlag = ((InitiateTaskMessage) notice).getDurabilityFlagIfItExists();
        m_task = null;
      }
    } else {
      m_task = null;
      m_durabilityFlag = null;
      m_invocation = null;
    }
  }