Ejemplo n.º 1
0
  /**
   * Releases the write lock held by the provided tx. If it is null then an attempt to acquire the
   * current transaction from the transaction manager will be made. This is to make safe calling
   * this method as an <code>afterCompletion()</code> hook where the transaction context is not
   * necessarily available. If write count is zero and there are waiting transactions in the queue
   * they will be interrupted if they can acquire the lock.
   */
  synchronized void releaseWriteLock(Object tx) throws LockNotFoundException {
    TxLockElement tle = getLockElement(tx);

    if (tle.writeCount == 0) {
      throw new LockNotFoundException("" + tx + " don't have writeLock");
    }

    totalWriteCount--;
    tle.writeCount--;
    if (tle.isFree()) {
      txLockElementMap.remove(tx);
      ragManager.lockReleased(this, tx);
    }

    // the threads in the waitingList cannot be currentThread
    // so we only have to wake other elements if writeCount is down to zero
    // (that is: If writeCount > 0 a waiting thread in the queue cannot be
    // the thread that holds the write locks because then it would never
    // have been put into wait mode)
    if (totalWriteCount == 0 && waitingThreadList.size() > 0) {
      // wake elements in queue until a write lock is found or queue is
      // empty
      do {
        WaitElement we = waitingThreadList.removeLast();
        if (!we.element.movedOn) {
          we.waitingThread.interrupt();
          if (we.lockType == LockType.WRITE) {
            break;
          }
        }
      } while (waitingThreadList.size() > 0);
    }
  }
Ejemplo n.º 2
0
 void commit(Transaction tx) {
   if (tx != null) {
     TxCommitHook hook = txCommitHooks.remove(tx);
     if (hook != null) {
       for (PropertyIndex index : hook.getAddedPropertyIndexes()) {
         addPropertyIndex(index);
       }
     }
   }
 }
Ejemplo n.º 3
0
 public Transaction suspend() throws SystemException {
   assertTmOk("tx suspend");
   // check for ACTIVE/MARKED_ROLLBACK?
   TransactionImpl tx = txThreadMap.remove(Thread.currentThread());
   if (tx != null) {
     // generate pro-active event suspend
     tx.markAsSuspended();
   }
   return tx;
 }
  @Test
  public void testArrayMap() {
    ArrayMap<String, Integer> map = new ArrayMap<String, Integer>();

    assertTrue(map.get("key1") == null);
    map.put("key1", 0);
    assertEquals(new Integer(0), map.get("key1"));
    assertEquals(new Integer(0), map.get("key1"));
    map.put("key1", 1);
    assertEquals(new Integer(1), map.get("key1"));
    map.put("key2", 0);
    assertEquals(new Integer(0), map.get("key2"));
    map.put("key2", 2);
    assertEquals(new Integer(2), map.get("key2"));
    assertEquals(new Integer(2), map.remove("key2"));
    assertTrue(map.get("key2") == null);
    assertEquals(new Integer(1), map.get("key1"));
    assertEquals(new Integer(1), map.remove("key1"));
    assertTrue(map.get("key1") == null);

    map.put("key1", 1);
    map.put("key2", 2);
    map.put("key3", 3);
    map.put("key4", 4);
    map.put("key5", 5);
    assertEquals(new Integer(5), map.get("key5"));
    assertEquals(new Integer(4), map.get("key4"));
    assertEquals(new Integer(3), map.get("key3"));
    assertEquals(new Integer(2), map.get("key2"));
    assertEquals(new Integer(1), map.get("key1"));
    assertEquals(new Integer(5), map.remove("key5"));
    assertEquals(new Integer(1), map.get("key1"));
    assertEquals(new Integer(4), map.get("key4"));
    assertEquals(new Integer(3), map.get("key3"));
    assertEquals(new Integer(2), map.get("key2"));
    assertEquals(new Integer(3), map.remove("key3"));
    assertEquals(new Integer(1), map.remove("key1"));
    assertEquals(new Integer(2), map.remove("key2"));

    for (int i = 0; i < 100; i++) {
      map.put("key" + i, i);
    }
    for (int i = 0; i < 100; i++) {
      assertEquals(new Integer(i), map.get("key" + i));
    }
    for (int i = 0; i < 100; i++) {
      assertEquals(new Integer(i), map.remove("key" + i));
    }
    for (int i = 0; i < 100; i++) {
      assertTrue(map.get("key" + i) == null);
    }
  }
Ejemplo n.º 5
0
  private void rollbackCommit(Thread thread, TransactionImpl tx)
      throws HeuristicMixedException, RollbackException, SystemException {
    try {
      tx.doRollback();
    } catch (XAException e) {
      log.log(
          Level.SEVERE,
          "Unable to rollback marked transaction. "
              + "Some resources may be commited others not. "
              + "Neo4j kernel should be SHUTDOWN for "
              + "resource maintance and transaction recovery ---->",
          e);
      setTmNotOk(e);
      throw logAndReturn(
          "TM error tx rollback commit",
          Exceptions.withCause(
              new HeuristicMixedException(
                  "Unable to rollback " + " ---> error code for rollback: " + e.errorCode),
              e));
    }

    tx.doAfterCompletion();
    txThreadMap.remove(thread);
    try {
      if (tx.isGlobalStartRecordWritten()) {
        getTxLog().txDone(tx.getGlobalId());
      }
    } catch (IOException e) {
      log.log(Level.SEVERE, "Error writing transaction log", e);
      setTmNotOk(e);
      throw logAndReturn(
          "TM error tx rollback commit",
          Exceptions.withCause(
              new SystemException("TM encountered a problem, " + " error writing transaction log"),
              e));
    }
    tx.setStatus(Status.STATUS_NO_TRANSACTION);
    throw new RollbackException("Failed to commit, transaction rolledback");
  }
Ejemplo n.º 6
0
 void rollback(Transaction tx) {
   txCommitHooks.remove(tx);
 }
Ejemplo n.º 7
0
  public void rollback() throws IllegalStateException, SystemException {
    assertTmOk("tx rollback");
    Thread thread = Thread.currentThread();
    TransactionImpl tx = txThreadMap.get(thread);
    if (tx == null) {
      throw new IllegalStateException("Not in transaction");
    }

    boolean hasAnyLocks = false;
    try {
      hasAnyLocks = finishHook.hasAnyLocks(tx);
      if (tx.getStatus() == Status.STATUS_ACTIVE
          || tx.getStatus() == Status.STATUS_MARKED_ROLLBACK
          || tx.getStatus() == Status.STATUS_PREPARING) {
        tx.setStatus(Status.STATUS_MARKED_ROLLBACK);
        tx.doBeforeCompletion();
        // delist resources?
        try {
          rolledBackTxCount.incrementAndGet();
          tx.doRollback();
        } catch (XAException e) {
          log.log(
              Level.SEVERE,
              "Unable to rollback marked or active transaction. "
                  + "Some resources may be commited others not. "
                  + "Neo4j kernel should be SHUTDOWN for "
                  + "resource maintance and transaction recovery ---->",
              e);
          setTmNotOk(e);
          throw logAndReturn(
              "TM error tx rollback",
              Exceptions.withCause(
                  new SystemException(
                      "Unable to rollback " + " ---> error code for rollback: " + e.errorCode),
                  e));
        }
        tx.doAfterCompletion();
        txThreadMap.remove(thread);
        try {
          if (tx.isGlobalStartRecordWritten()) {
            getTxLog().txDone(tx.getGlobalId());
          }
        } catch (IOException e) {
          log.log(Level.SEVERE, "Error writing transaction log", e);
          setTmNotOk(e);
          throw logAndReturn(
              "TM error tx rollback",
              Exceptions.withCause(
                  new SystemException(
                      "TM encountered a problem, " + " error writing transaction log"),
                  e));
        }
        tx.setStatus(Status.STATUS_NO_TRANSACTION);
      } else {
        throw new IllegalStateException("Tx status is: " + getTxStatusAsString(tx.getStatus()));
      }
    } finally {
      if (hasAnyLocks) {
        finishHook.finishTransaction(tx.getEventIdentifier(), false);
      }
    }
  }
Ejemplo n.º 8
0
 private void commit(Thread thread, TransactionImpl tx)
     throws SystemException, HeuristicMixedException, HeuristicRollbackException {
   // mark as commit in log done TxImpl.doCommit()
   Throwable commitFailureCause = null;
   int xaErrorCode = -1;
   if (tx.getResourceCount() == 0) {
     tx.setStatus(Status.STATUS_COMMITTED);
   } else {
     try {
       tx.doCommit();
     } catch (XAException e) {
       xaErrorCode = e.errorCode;
       log.log(
           Level.SEVERE,
           "Commit failed, status="
               + getTxStatusAsString(tx.getStatus())
               + ", errorCode="
               + xaErrorCode,
           e);
       if (tx.getStatus() == Status.STATUS_COMMITTED) {
         // this should never be
         setTmNotOk(e);
         throw logAndReturn(
             "TM error tx commit",
             new TransactionFailureException(
                 "commit threw exception but status is committed?", e));
       }
     } catch (Throwable t) {
       log.log(Level.SEVERE, "Commit failed", t);
       commitFailureCause = t;
     }
   }
   if (tx.getStatus() != Status.STATUS_COMMITTED) {
     try {
       tx.doRollback();
     } catch (Throwable e) {
       log.log(
           Level.SEVERE,
           "Unable to rollback transaction. "
               + "Some resources may be commited others not. "
               + "Neo4j kernel should be SHUTDOWN for "
               + "resource maintance and transaction recovery ---->",
           e);
       setTmNotOk(e);
       String commitError;
       if (commitFailureCause != null) {
         commitError = "error in commit: " + commitFailureCause;
       } else {
         commitError = "error code in commit: " + xaErrorCode;
       }
       String rollbackErrorCode = "Uknown error code";
       if (e instanceof XAException) {
         rollbackErrorCode = Integer.toString(((XAException) e).errorCode);
       }
       throw logAndReturn(
           "TM error tx commit",
           Exceptions.withCause(
               new HeuristicMixedException(
                   "Unable to rollback ---> "
                       + commitError
                       + " ---> error code for rollback: "
                       + rollbackErrorCode),
               e));
     }
     tx.doAfterCompletion();
     txThreadMap.remove(thread);
     try {
       if (tx.isGlobalStartRecordWritten()) {
         getTxLog().txDone(tx.getGlobalId());
       }
     } catch (IOException e) {
       log.log(Level.SEVERE, "Error writing transaction log", e);
       setTmNotOk(e);
       throw logAndReturn(
           "TM error tx commit",
           Exceptions.withCause(
               new SystemException(
                   "TM encountered a problem, " + " error writing transaction log"),
               e));
     }
     tx.setStatus(Status.STATUS_NO_TRANSACTION);
     if (commitFailureCause == null) {
       throw logAndReturn(
           "TM error tx commit",
           new HeuristicRollbackException(
               "Failed to commit, transaction rolledback ---> "
                   + "error code was: "
                   + xaErrorCode));
     } else {
       throw logAndReturn(
           "TM error tx commit",
           Exceptions.withCause(
               new HeuristicRollbackException(
                   "Failed to commit, transaction rolledback ---> " + commitFailureCause),
               commitFailureCause));
     }
   }
   tx.doAfterCompletion();
   txThreadMap.remove(thread);
   try {
     if (tx.isGlobalStartRecordWritten()) {
       getTxLog().txDone(tx.getGlobalId());
     }
   } catch (IOException e) {
     log.log(Level.SEVERE, "Error writing transaction log", e);
     setTmNotOk(e);
     throw logAndReturn(
         "TM error tx commit",
         Exceptions.withCause(
             new SystemException("TM encountered a problem, " + " error writing transaction log"),
             e));
   }
   tx.setStatus(Status.STATUS_NO_TRANSACTION);
 }
 synchronized void stopWaitOn(Object resource, Transaction tx) {
   if (waitingTxMap.remove(tx) == null) {
     throw new LockException(tx + " not waiting on " + resource);
   }
 }
Ejemplo n.º 10
0
 void releaseResourceConnectionsForTransaction(Transaction tx) throws NotInTransactionException {
   T con = txConnectionMap.remove(tx);
   if (con != null) {
     con.destroy();
   }
 }
Ejemplo n.º 11
0
  /**
   * Releases the read lock held by the provided transaction. If it is null then an attempt to
   * acquire the current transaction will be made. This is to make safe calling the method from the
   * context of an <code>afterCompletion()</code> hook where the tx is locally stored and not
   * necessarily available through the tm. If there are waiting transactions in the queue they will
   * be interrupted if they can acquire the lock.
   */
  synchronized void releaseReadLock(Object tx) throws LockNotFoundException {
    TxLockElement tle = getLockElement(tx);

    if (tle.readCount == 0) {
      throw new LockNotFoundException("" + tx + " don't have readLock");
    }

    totalReadCount--;
    tle.readCount--;
    if (tle.isFree()) {
      txLockElementMap.remove(tx);
      ragManager.lockReleased(this, tx);
    }
    if (waitingThreadList.size() > 0) {
      WaitElement we = waitingThreadList.getLast();

      if (we.lockType == LockType.WRITE) {
        // this one is tricky...
        // if readCount > 0 we either have to find a waiting read lock
        // in the queue or a waiting write lock that has all read
        // locks, if none of these are found it means that there
        // is a (are) thread(s) that will release read lock(s) in the
        // near future...
        if (totalReadCount == we.element.readCount) {
          // found a write lock with all read locks
          waitingThreadList.removeLast();
          if (!we.element.movedOn) {
            we.waitingThread.interrupt();
          }
        } else {
          ListIterator<WaitElement> listItr =
              waitingThreadList.listIterator(waitingThreadList.lastIndexOf(we));
          // hm am I doing the first all over again?
          // think I am if cursor is at lastIndex + 0.5 oh well...
          while (listItr.hasPrevious()) {
            we = listItr.previous();
            if (we.lockType == LockType.WRITE && totalReadCount == we.element.readCount) {
              // found a write lock with all read locks
              listItr.remove();
              if (!we.element.movedOn) {
                we.waitingThread.interrupt();
                // ----
                break;
              }
            } else if (we.lockType == LockType.READ) {
              // found a read lock, let it do the job...
              listItr.remove();
              if (!we.element.movedOn) {
                we.waitingThread.interrupt();
              }
            }
          }
        }
      } else {
        // some thread may have the write lock and released a read lock
        // if writeCount is down to zero we can interrupt the waiting
        // read lock
        if (totalWriteCount == 0) {
          waitingThreadList.removeLast();
          if (!we.element.movedOn) {
            we.waitingThread.interrupt();
          }
        }
      }
    }
  }