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); } }
/** * 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); } } } }