GraphDiff onSyncRollback(ObjectContext originatingContext) {
    // if there is a transaction in progress, roll it back

    Transaction transaction = Transaction.getThreadTransaction();
    if (transaction != null) {
      transaction.setRollbackOnly();
    }

    return new CompoundDiff();
  }
  /** @since 3.0 */
  @Override
  protected long longPkFromDatabase(DataNode node, DbEntity entity) throws Exception {
    // handle CAY-588 - get connection that is separate from the connection in the
    // current transaction.

    // TODO (andrus, 7/6/2006) Note that this will still work in a pool with a single
    // connection, as PK generator is invoked early in the transaction, before the
    // connection is grabbed for commit... So maybe promote this to other adapters in
    // 3.0?

    Transaction transaction = Transaction.getThreadTransaction();
    Transaction.bindThreadTransaction(null);

    try {

      Connection connection = node.getDataSource().getConnection();
      try {
        CallableStatement statement = connection.prepareCall("{call auto_pk_for_table(?, ?)}");
        try {
          statement.setString(1, entity.getName());
          statement.setInt(2, super.getPkCacheSize());

          // can't use "executeQuery"
          // per http://jtds.sourceforge.net/faq.html#expectingResultSet
          statement.execute();
          if (statement.getMoreResults()) {
            ResultSet rs = statement.getResultSet();

            try {
              if (rs.next()) {
                return rs.getLong(1);
              } else {
                throw new CayenneRuntimeException(
                    "Error generating pk for DbEntity " + entity.getName());
              }
            } finally {
              rs.close();
            }
          } else {
            throw new CayenneRuntimeException(
                "Error generating pk for DbEntity "
                    + entity.getName()
                    + ", no result set from stored procedure.");
          }
        } finally {
          statement.close();
        }
      } finally {
        connection.close();
      }
    } finally {
      Transaction.bindThreadTransaction(transaction);
    }
  }
Example #3
0
  /**
   * Helper method that wraps a number of queries in this transaction, runs them, and commits or
   * rolls back depending on the outcome. This method allows users to define their own custom
   * Transactions and wrap Cayenne queries in them.
   *
   * @deprecated since 1.2 this method is not used in Cayenne and is deprecated. Thread-bound
   *     transactions should be used instead.
   */
  @Deprecated
  public void performQueries(QueryEngine engine, Collection queries, OperationObserver observer)
      throws CayenneRuntimeException {

    Transaction old = Transaction.getThreadTransaction();
    Transaction.bindThreadTransaction(this);

    try {
      // implicit begin..
      engine.performQueries(queries, observer);

      // don't commit iterated queries - leave it up to the caller
      // at the same time rollbacks of iterated queries must be processed here,
      // since caller will no longer be processing stuff on exception
      if (!observer.isIteratedResult() && (getStatus() == Transaction.STATUS_ACTIVE)) {
        commit();
      }
    } catch (Exception ex) {
      setRollbackOnly();

      // must rethrow
      if (ex instanceof CayenneRuntimeException) {
        throw (CayenneRuntimeException) ex;
      } else {
        throw new CayenneRuntimeException(ex);
      }
    } finally {
      Transaction.bindThreadTransaction(old);
      if (getStatus() == Transaction.STATUS_MARKED_ROLLEDBACK) {
        try {
          rollback();
        } catch (Exception rollbackEx) {
        }
      }
    }
  }
 /**
  * Creates and returns a new inactive transaction. Returned transaction is bound to the current
  * execution thread.
  *
  * <p>If there is a TransactionDelegate, adds the delegate to the newly created Transaction.
  * Behavior of the returned Transaction depends on "usingInternalTransactions" property setting.
  *
  * @since 1.1
  */
 public Transaction createTransaction() {
   if (isUsingExternalTransactions()) {
     Transaction transaction = Transaction.externalTransaction(getTransactionDelegate());
     transaction.setJdbcEventLogger(jdbcEventLogger);
     return transaction;
   } else {
     Transaction transaction = Transaction.internalTransaction(getTransactionDelegate());
     transaction.setJdbcEventLogger(jdbcEventLogger);
     return transaction;
   }
 }
  // WARNING: (andrus) if we ever decide to make this method protected or public, we
  // need to change the signature to avoid API dependency on commons-collections
  Object runInTransaction(Transformer operation) {

    // user or container-managed or nested transaction
    if (Transaction.getThreadTransaction() != null) {
      return operation.transform(null);
    }

    // Cayenne-managed transaction

    Transaction transaction = createTransaction();
    Transaction.bindThreadTransaction(transaction);

    try {
      // implicit begin..
      Object result = operation.transform(null);
      transaction.commit();
      return result;
    } catch (Exception ex) {
      transaction.setRollbackOnly();

      // must rethrow
      if (ex instanceof CayenneRuntimeException) {
        throw (CayenneRuntimeException) ex;
      } else {
        throw new CayenneRuntimeException(ex);
      }
    } finally {
      Transaction.bindThreadTransaction(null);
      if (transaction.getStatus() == Transaction.STATUS_MARKED_ROLLEDBACK) {
        try {
          transaction.rollback();
        } catch (Exception rollbackEx) {
          // although we don't expect an exception here, print the stack, as
          // there have been some Cayenne bugs already (CAY-557) that were
          // masked by this 'catch' clause.
          jdbcEventLogger.logQueryError(rollbackEx);
        }
      }
    }
  }