/** {@inheritDoc} */
  @Override
  public boolean onDone(GridCacheTx tx, Throwable err) {
    if ((initialized() || err != null) && super.onDone(tx, err)) {
      if (error() instanceof GridCacheTxHeuristicException) {
        long topVer = this.tx.topologyVersion();

        for (GridCacheTxEntry<K, V> e : this.tx.writeMap().values()) {
          try {
            if (e.op() != NOOP && !cctx.affinity().localNode(e.key(), topVer)) {
              GridCacheEntryEx<K, V> cacheEntry = cctx.cache().peekEx(e.key());

              if (cacheEntry != null) cacheEntry.invalidate(null, this.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(this);

      return true;
    }

    return false;
  }
예제 #2
0
  /** @return {@code True} if locks have been acquired. */
  private boolean checkLocks() {
    if (!isDone() && initialized() && !hasPending()) {
      for (int i = 0; i < entries.size(); i++) {
        while (true) {
          GridCacheEntryEx<K, V> cached = entries.get(i);

          try {
            if (!locked(cached)) {
              if (log.isDebugEnabled())
                log.debug(
                    "Lock is still not acquired for entry (will keep waiting) [entry="
                        + cached
                        + ", fut="
                        + this
                        + ']');

              return false;
            }

            break;
          }
          // Possible in concurrent cases, when owner is changed after locks
          // have been released or cancelled.
          catch (GridCacheEntryRemovedException ignore) {
            if (log.isDebugEnabled())
              log.debug("Got removed entry in onOwnerChanged method (will retry): " + cached);

            // Replace old entry with new one.
            entries.set(i, (GridDistributedCacheEntry<K, V>) cctx.cache().entryEx(cached.key()));
          }
        }
      }

      if (log.isDebugEnabled())
        log.debug("Local lock acquired for entries [fut=" + this + ", entries=" + entries + "]");

      onComplete(true, true);

      return true;
    }

    return false;
  }
예제 #3
0
  /**
   * Undoes all locks.
   *
   * @param dist If {@code true}, then remove locks from remote nodes as well.
   */
  private void undoLocks(boolean dist) {
    // Transactions will undo during rollback.
    if (dist && tx == null) cctx.nearTx().removeLocks(lockVer, keys);
    else {
      if (tx != null) {
        if (tx.setRollbackOnly()) {
          if (log.isDebugEnabled())
            log.debug(
                "Marked transaction as rollback only because locks could not be acquired: " + tx);
        } else if (log.isDebugEnabled())
          log.debug(
              "Transaction was not marked rollback-only while locks were not acquired: " + tx);
      }

      for (GridCacheEntryEx<K, V> e : entriesCopy()) {
        try {
          e.removeLock(lockVer);
        } catch (GridCacheEntryRemovedException ignored) {
          while (true) {
            try {
              e = cctx.cache().peekEx(e.key());

              if (e != null) e.removeLock(lockVer);

              break;
            } catch (GridCacheEntryRemovedException ignore) {
              if (log.isDebugEnabled())
                log.debug(
                    "Attempted to remove lock on removed entry (will retry) [ver="
                        + lockVer
                        + ", entry="
                        + e
                        + ']');
            }
          }
        }
      }
    }

    cctx.mvcc().recheckPendingLocks();
  }
예제 #4
0
 /**
  * @param cached Entry.
  * @return {@code True} if locked.
  * @throws GridCacheEntryRemovedException If removed.
  */
 private boolean locked(GridCacheEntryEx<K, V> cached) throws GridCacheEntryRemovedException {
   // Reentry-aware check (If filter failed, lock is failed).
   return cached.lockedLocallyByIdOrThread(lockVer, threadId) && filter(cached);
 }