/** * 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; } }