예제 #1
0
 private void invokeCallbacks(Callback<Void>[] callbacks, Throwable e) {
   for (Callback<Void> callback : callbacks) {
     try {
       callback.onDone(null, e);
     } catch (Throwable e2) {
       Log.error("Transaction callback error", e2);
     }
   }
 }
예제 #2
0
  /**
   * ACID transactional semantics:<br>
   * - Atomicity with automatic rollback in case of exception,<br>
   * - Consistency - only with constraints enforced programmatically inside transaction,<br>
   * - Isolation is serializable (with global lock),<br>
   * - Durability through on-commit callbacks.<br>
   */
  public void transaction(Runnable transaction, boolean readOnly, Callback<Void> txCallback) {
    globalLock();

    data.txIdCounter.set(data.ids.get());
    data.txChanges.clear();
    data.txInsertions.clear();
    data.txReadonly.set(readOnly);
    data.insideTx.set(true);

    boolean success = false;
    try {
      transaction.run();
      success = true;

    } catch (Throwable e) {
      if (SuccessException.isSuccess(e)) {
        success = true;
        throw U.rte(e);
      } else {
        Log.error("Error in transaction, rolling back", e);
        txRollback();
        if (txCallback != null) {
          txCallback.onDone(null, e);
          txCallback = null;
        }
      }

    } finally {
      data.txChanges.clear();
      data.txInsertions.clear();
      data.insideTx.set(false);

      if (persistor != null) {
        if (success && txCallback != null) {
          data.txCallbacks.add(txCallback);
        }
      } else {
        if (success && txCallback != null) {
          txCallback.onDone(null, null);
        }
      }

      globalUnlock();
    }
  }