Exemple #1
0
  /**
   * @param entry Entry to enlist.
   * @throws IgniteCheckedException If failed.
   * @return {@code True} if entry was enlisted.
   */
  private boolean addEntry(IgniteTxEntry entry) throws IgniteCheckedException {
    checkInternal(entry.txKey());

    GridCacheContext cacheCtx = entry.context();

    if (!cacheCtx.isNear()) cacheCtx = cacheCtx.dht().near().context();

    GridNearCacheEntry cached = cacheCtx.near().peekExx(entry.key());

    if (cached == null) {
      evicted.add(entry.txKey());

      return false;
    } else {
      try {
        cached.unswap();

        CacheObject val = cached.peek(true, false, false, null);

        if (val == null && cached.evictInternal(false, xidVer, null)) {
          evicted.add(entry.txKey());

          return false;
        } else {
          // Initialize cache entry.
          entry.cached(cached);

          txState.addWriteEntry(entry.txKey(), entry);

          addExplicit(entry);

          return true;
        }
      } catch (GridCacheEntryRemovedException ignore) {
        evicted.add(entry.txKey());

        if (log.isDebugEnabled())
          log.debug("Got removed entry when adding to remote transaction (will ignore): " + cached);

        return false;
      }
    }
  }
  /**
   * @param entries Entries.
   * @param dhtVer DHT version.
   * @param pendingVers Pending versions.
   * @param committedVers Committed versions.
   * @param rolledbackVers Rolled back versions.
   */
  void readyNearLocks(
      Collection<IgniteTxEntry> entries,
      GridCacheVersion dhtVer,
      Collection<GridCacheVersion> pendingVers,
      Collection<GridCacheVersion> committedVers,
      Collection<GridCacheVersion> rolledbackVers) {
    for (IgniteTxEntry txEntry : entries) {
      while (true) {
        GridCacheContext cacheCtx = txEntry.cached().context();

        assert cacheCtx.isNear();

        GridDistributedCacheEntry entry = (GridDistributedCacheEntry) txEntry.cached();

        try {
          // Handle explicit locks.
          GridCacheVersion explicit = txEntry.explicitVersion();

          if (explicit == null) {
            entry.readyNearLock(xidVer, dhtVer, committedVers, rolledbackVers, pendingVers);
          }

          break;
        } catch (GridCacheEntryRemovedException ignored) {
          assert entry.obsoleteVersion() != null;

          if (log.isDebugEnabled())
            log.debug(
                "Replacing obsolete entry in remote transaction [entry="
                    + entry
                    + ", tx="
                    + this
                    + ']');

          // Replace the entry.
          txEntry.cached(txEntry.context().cache().entryEx(txEntry.key()));
        }
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public boolean onDone(IgniteInternalTx tx0, Throwable err) {
    if (isDone()) return false;

    synchronized (this) {
      if (isDone()) return false;

      if (err != null) {
        tx.commitError(err);

        boolean marked = tx.setRollbackOnly();

        if (err instanceof IgniteTxRollbackCheckedException) {
          if (marked) {
            try {
              tx.rollback();
            } catch (IgniteCheckedException ex) {
              U.error(log, "Failed to automatically rollback transaction: " + tx, ex);
            }
          }
        } else if (tx.implicit()
            && tx.isSystemInvalidate()) { // Finish implicit transaction on heuristic error.
          try {
            tx.close();
          } catch (IgniteCheckedException ex) {
            U.error(log, "Failed to invalidate transaction: " + tx, ex);
          }
        }
      }

      if (initialized() || err != null) {
        if (tx.needCheckBackup()) {
          assert tx.onePhaseCommit();

          if (err != null)
            err = new TransactionRollbackException("Failed to commit transaction.", err);

          try {
            tx.finish(err == null);
          } catch (IgniteCheckedException e) {
            if (err != null) err.addSuppressed(e);
            else err = e;
          }
        }

        if (tx.onePhaseCommit()) {
          boolean commit = this.commit && err == null;

          finishOnePhase(commit);

          tx.tmFinish(commit);
        }

        if (super.onDone(tx0, err)) {
          if (error() instanceof IgniteTxHeuristicCheckedException) {
            AffinityTopologyVersion topVer = tx.topologyVersion();

            for (IgniteTxEntry e : tx.writeMap().values()) {
              GridCacheContext cacheCtx = e.context();

              try {
                if (e.op() != NOOP && !cacheCtx.affinity().localNode(e.key(), topVer)) {
                  GridCacheEntryEx entry = cacheCtx.cache().peekEx(e.key());

                  if (entry != null) entry.invalidate(null, tx.xidVersion());
                }
              } catch (Throwable t) {
                U.error(log, "Failed to invalidate entry.", t);

                if (t instanceof Error) throw (Error) t;
              }
            }
          }

          // Don't forget to clean up.
          cctx.mvcc().removeFuture(futId);

          return true;
        }
      }
    }

    return false;
  }