@Override public Object visitPutForExternalReadCommand(InvocationContext ctx, PutForExternalReadCommand command) throws Throwable { // these are always local more, as far as invalidation is concerned if (ctx.getTransaction() != null) ctx.getTransactionContext().addLocalModification(command); return invokeNextInterceptor(ctx, command); }
@Override public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable { Object retval = invokeNextInterceptor(ctx, command); Transaction tx = ctx.getTransaction(); if (tx != null && optimistic) { GlobalTransaction gtx = ctx.getGlobalTransaction(); txMods.remove(gtx); log.debug("Caught a rollback. Clearing modification in txMods"); } return retval; }
protected Object attachGtxAndPassUpChain(InvocationContext ctx, VisitableCommand command) throws Throwable { Transaction tx = ctx.getTransaction(); if (tx != null) attachGlobalTransaction(ctx, tx, command); return invokeNextInterceptor(ctx, command); }
/** * It does not make sense replicating a transaction method(commit, rollback, prepare) if one of the following is true: * <pre> * - call was not initiated here, but on other member of the cluster * - there is no transaction. Why broadcast a commit or rollback if there is no transaction going on? * - the current transaction did not modify any data * </pre> */ protected boolean skipReplicationOfTransactionMethod(InvocationContext ctx) { GlobalTransaction gtx = ctx.getGlobalTransaction(); return ctx.getTransaction() == null || gtx == null || gtx.isRemote() || ctx.getOptionOverrides().isCacheModeLocal() || !ctx.getTransactionContext().hasModifications(); }
@Override public Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable { Object result = invokeNextInterceptor(ctx, command); assertTxIsStillValid(ctx.getTransaction()); return result; }
@Override public Object visitPutForExternalReadCommand(InvocationContext ctx, PutForExternalReadCommand command) throws Throwable { boolean local = isLocalModeForced(ctx); if (local && ctx.getTransaction() == null) return invokeNextInterceptor(ctx, command); if (isTransactionalAndLocal(ctx)) { Object returnValue = invokeNextInterceptor(ctx, command); ctx.getTransactionContext().setForceAsyncReplication(true); if (local) ctx.getTransactionContext().addLocalModification(command); return returnValue; } else { return handleCrudMethod(ctx, command, true); } }
@Override public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable { Object retval = invokeNextInterceptor(ctx, command); notifier.notifyTransactionCompleted(ctx.getTransaction(), true, ctx); return retval; }
@Override public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable { Object retval = invokeNextInterceptor(ctx, command); notifier.notifyTransactionCompleted(ctx.getTransaction(), false, ctx); return retval; } }
/** * The call runs in a transaction and it was initiated on this node of the cluster. */ protected boolean isTransactionalAndLocal(InvocationContext ctx) { GlobalTransaction gtx = ctx.getGlobalTransaction(); boolean isInitiatedHere = gtx != null && !gtx.isRemote(); return isInitiatedHere && (ctx.getTransaction() != null); }
@Override public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable { Object retval = invokeNextInterceptor(ctx, command); Transaction tx = ctx.getTransaction(); if (tx != null && optimistic) { GlobalTransaction gtx = ctx.getGlobalTransaction(); List<WriteCommand> modifications = txMods.remove(gtx); broadcastInvalidate(modifications, tx, ctx); if (trace) log.trace("Committing. Broadcasting invalidations."); } return retval; }
@Override public Object visitPrepareCommand(InvocationContext ctx, PrepareCommand command) throws Throwable { Object retval = invokeNextInterceptor(ctx, command); if (command.isOnePhaseCommit()) notifier.notifyTransactionCompleted(ctx.getTransaction(), true, ctx); return retval; }
/** * @return the {@link org.jboss.cache.transaction.GlobalTransaction}, extracted from the current {@link org.jboss.cache.InvocationContext}. * @throws CacheException if the {@link org.jboss.cache.transaction.GlobalTransaction} or {@link javax.transaction.Transaction} associated with the * {@link org.jboss.cache.InvocationContext} is null. */ protected GlobalTransaction getGlobalTransaction(InvocationContext ctx) throws CacheException { Transaction tx = ctx.getTransaction(); if (tx == null) throw new CacheException("Transaction associated with the current invocation is null!"); GlobalTransaction gtx = ctx.getGlobalTransaction(); if (gtx == null) throw new CacheException("GlobalTransaction associated with the current invocation is null!"); return gtx; }
/** * Tests whether the caller is in a valid transaction. If not, will throw a CacheException. */ public static void assertTransactionValid(InvocationContext ctx) { Transaction tx = ctx.getTransaction(); if (!isValid(tx)) { try { throw new CacheException("Invalid transaction " + tx + ", status = " + (tx == null ? null : tx.getStatus())); } catch (SystemException e) { throw new CacheException("Exception trying to analyse status of transaction " + tx, e); } } }
/** * Sets the state of the InvocationContext based on the template context passed in * * @param template template to copy from */ public void setState(InvocationContext template) { if (template == null) { throw new NullPointerException("Template InvocationContext passed in to InvocationContext.setState() passed in is null"); } this.setGlobalTransaction(template.getGlobalTransaction()); this.setLocalRollbackOnly(template.isLocalRollbackOnly()); this.setOptionOverrides(template.getOptionOverrides()); this.setOriginLocal(template.isOriginLocal()); this.setTransaction(template.getTransaction()); }
public void notifyNodeVisited(Fqn fqn, boolean pre, InvocationContext ctx) { if (!nodeVisitedListeners.isEmpty() && !ctx.getOptionOverrides().isSuppressEventNotification()) { Transaction tx = ctx.getTransaction(); InvocationContext backup = resetInvocationContext(ctx); EventImpl e = new EventImpl(); e.setCache(cache); e.setPre(pre); e.setFqn(fqn); e.setTransaction(tx); e.setType(NODE_VISITED); for (ListenerInvocation listener : nodeVisitedListeners) listener.invoke(e); restoreInvocationContext(backup); } }
public void notifyNodePassivated(Fqn fqn, boolean pre, Map data, InvocationContext ctx) { if (!nodePassivatedListeners.isEmpty() && !ctx.getOptionOverrides().isSuppressEventNotification()) { Map dataCopy = copy(data, useMarshalledValueMaps); Transaction tx = ctx.getTransaction(); InvocationContext backup = resetInvocationContext(ctx); EventImpl e = new EventImpl(); e.setCache(cache); e.setPre(pre); e.setFqn(fqn); e.setTransaction(tx); e.setData(dataCopy); e.setType(NODE_PASSIVATED); for (ListenerInvocation listener : nodePassivatedListeners) listener.invoke(e); restoreInvocationContext(backup); } }
public void notifyNodeInvalidated(final Fqn fqn, final boolean pre, InvocationContext ctx) { if (!nodeInvalidatedListeners.isEmpty() && !ctx.getOptionOverrides().isSuppressEventNotification()) { final boolean originLocal = ctx.isOriginLocal(); Transaction tx = ctx.getTransaction(); InvocationContext backup = resetInvocationContext(ctx); EventImpl e = new EventImpl(); e.setCache(cache); e.setOriginLocal(originLocal); e.setPre(pre); e.setFqn(fqn); e.setTransaction(tx); e.setType(NODE_INVALIDATED); for (ListenerInvocation listener : nodeInvalidatedListeners) listener.invoke(e); restoreInvocationContext(backup); } }
public void notifyNodeCreated(Fqn fqn, boolean pre, InvocationContext ctx) { if (!nodeCreatedListeners.isEmpty() && !ctx.getOptionOverrides().isSuppressEventNotification()) { boolean originLocal = ctx.isOriginLocal(); Transaction tx = ctx.getTransaction(); InvocationContext backup = resetInvocationContext(ctx); EventImpl e = new EventImpl(); e.setCache(cache); e.setOriginLocal(originLocal); e.setPre(pre); e.setFqn(fqn); e.setTransaction(tx); e.setType(NODE_CREATED); for (ListenerInvocation listener : nodeCreatedListeners) listener.invoke(e); restoreInvocationContext(backup); } }
public void notifyNodeEvicted(final Fqn fqn, final boolean pre, InvocationContext ctx) { if (!nodeEvictedListeners.isEmpty() && !ctx.getOptionOverrides().isSuppressEventNotification()) { final boolean originLocal = ctx.isOriginLocal(); Transaction tx = ctx.getTransaction(); InvocationContext backup = resetInvocationContext(ctx); EventImpl e = new EventImpl(); e.setCache(cache); e.setOriginLocal(originLocal); e.setPre(pre); e.setFqn(fqn); e.setTransaction(tx); e.setType(NODE_EVICTED); for (ListenerInvocation listener : nodeEvictedListeners) listener.invoke(e); restoreInvocationContext(backup); } }
public void notifyNodeActivated(Fqn fqn, boolean pre, Map data, InvocationContext ctx) { if (!nodeActivatedListeners.isEmpty() && !ctx.getOptionOverrides().isSuppressEventNotification()) { boolean originLocal = ctx.isOriginLocal(); Map dataCopy = copy(data, useMarshalledValueMaps); Transaction tx = ctx.getTransaction(); InvocationContext backup = resetInvocationContext(ctx); EventImpl e = new EventImpl(); e.setCache(cache); e.setOriginLocal(originLocal); e.setPre(pre); e.setFqn(fqn); e.setTransaction(tx); e.setData(dataCopy); e.setType(NODE_ACTIVATED); for (ListenerInvocation listener : nodeActivatedListeners) listener.invoke(e); restoreInvocationContext(backup); } }