/** * Resume the given transaction. Delegates to the {@code doResume} * template method first, then resuming transaction synchronization. * @param transaction the current transaction object * @param resourcesHolder the object that holds suspended resources, * as returned by {@code suspend} (or {@code null} to just * resume synchronizations, if any) * @see #doResume * @see #suspend */ protected final void resume(Object transaction, SuspendedResourcesHolder resourcesHolder) throws TransactionException { if (resourcesHolder != null) { Object suspendedResources = resourcesHolder.suspendedResources; if (suspendedResources != null) { doResume(transaction, suspendedResources); } List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations; if (suspendedSynchronizations != null) { TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive); TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel); TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly); TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name); doResumeSynchronization(suspendedSynchronizations); } } }
@Override public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { Transaction.IsolationLevel isolationLevel = translateIsolationLevel(definition.getIsolationLevel()); Transaction t; if (isolationLevel == null) { t = sql.transaction(); } else { t = sql.transaction(isolationLevel); } if (definition.isReadOnly()) { Wrap.execute(() -> t.getConnection().setReadOnly(true)); } return new SqlStreamTransactionStatus(t); }
/** * Start a new transaction. Only call this method if {@link #endTransaction()} has been called. * {@link #setComplete()} can be used again in the new transaction. The fate of the new transaction, by default, * will be the usual rollback. * * @throws TransactionException if starting the transaction failed */ protected void startNewTransaction() throws TransactionException { if (this.transactionStatus != null) { throw new IllegalStateException("Cannot start new transaction without ending existing transaction: " + "Invoke endTransaction() before startNewTransaction()"); } if (this.transactionManager == null) { throw new IllegalStateException("No transaction manager set"); } this.transactionStatus = this.transactionManager.getTransaction(this.transactionDefinition); ++this.transactionsStarted; this.complete = !this.isRollback(); }
@Override public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException { OpenJPAEntityManager openJpaEntityManager = getOpenJPAEntityManager(entityManager); if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { // Pass custom isolation level on to OpenJPA's JDBCFetchPlan configuration FetchPlan fetchPlan = openJpaEntityManager.getFetchPlan(); if (fetchPlan instanceof JDBCFetchPlan) { IsolationLevel isolation = IsolationLevel.fromConnectionConstant(definition.getIsolationLevel()); ((JDBCFetchPlan) fetchPlan).setIsolation(isolation); } } entityManager.getTransaction().begin(); if (!definition.isReadOnly()) { // Like with EclipseLink, make sure to start the logic transaction early so that other // participants using the connection (such as JdbcTemplate) run in a transaction. openJpaEntityManager.beginStore(); } // Custom implementation for OpenJPA savepoint handling return new OpenJpaTransactionData(openJpaEntityManager); }
@Override public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException { if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { // Pass custom isolation level on to EclipseLink's DatabaseLogin configuration // (since Spring 4.1.2) UnitOfWork uow = entityManager.unwrap(UnitOfWork.class); uow.getLogin().setTransactionIsolation(definition.getIsolationLevel()); } entityManager.getTransaction().begin(); if (!definition.isReadOnly() && !this.lazyDatabaseTransaction) { // Begin an early transaction to force EclipseLink to get a JDBC Connection // so that Spring can manage transactions with JDBC as well as EclipseLink. entityManager.unwrap(UnitOfWork.class).beginEarlyTransaction(); } return null; }
/** * Start a new transaction. Only call this method if * {@link #endTransaction()} has been called. {@link #setComplete()} can be * used again in the new transaction. The fate of the new transaction, by * default, will be the usual rollback. * @throws TransactionException if starting the transaction failed */ protected void startNewTransaction() throws TransactionException { if (this.transactionStatus != null) { throw new IllegalStateException("Cannot start new transaction without ending existing transaction: " + "Invoke endTransaction() before startNewTransaction()"); } if (this.transactionManager == null) { throw new IllegalStateException("No transaction manager set"); } this.transactionStatus = this.transactionManager.getTransaction(this.transactionDefinition); ++this.transactionsStarted; this.complete = !this.isRollback(); if (this.logger.isDebugEnabled()) { this.logger.debug("Began transaction (" + this.transactionsStarted + "): transaction manager [" + this.transactionManager + "]; rollback [" + this.isRollback() + "]."); } }
@Override public Object beginTransaction(final EntityManager entityManager, final TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException { Session session = (Session) entityManager.getDelegate(); if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) { getSession(entityManager).getTransaction().setTimeout(definition.getTimeout()); } entityManager.getTransaction().begin(); logger.debug("Transaction started"); session.doWork(new Work() { @Override public void execute(Connection connection) throws SQLException { logger.debug("The connection instance is " + connection.toString()); logger.debug("The isolation level of the connection is " + connection.getTransactionIsolation() + " and the isolation level set on the transaction is " + definition.getIsolationLevel() ); DataSourceUtils.prepareConnectionForTransaction(connection, definition); } }); return prepareTransaction(entityManager, definition.isReadOnly(), definition.getName()); }
@Override protected Object doGetTransaction() throws TransactionException { JiniTransactionObject txObject = new JiniTransactionObject(); // txObject.setNestedTransactionAllowed // txObject.setJiniHolder(transactionalContext); // set the jini holder is one is found JiniTransactionHolder jiniHolder = (JiniTransactionHolder) TransactionSynchronizationManager.getResource(transactionalContext); if (jiniHolder == null) { jiniHolder = (JiniTransactionHolder) TransactionSynchronizationManager.getResource(ExistingJiniTransactionManager.CONTEXT); } if (jiniHolder != null) { if (logger.isTraceEnabled()) { logger.trace(logMessage("Found thread-bound tx data [" + jiniHolder + "] for Jini resource [" + transactionalContext + "]")); } txObject.setJiniHolder(jiniHolder, false); } return txObject; }
private long createActionsForRolloutGroup(final Rollout rollout, final RolloutGroup group) { long totalActionsCreated = 0; try { long actionsCreated; do { actionsCreated = createActionsForTargetsInNewTransaction(rollout.getId(), group.getId(), TRANSACTION_TARGETS); totalActionsCreated += actionsCreated; } while (actionsCreated > 0); } catch (final TransactionException e) { LOGGER.warn("Transaction assigning Targets to RolloutGroup failed", e); return 0; } return totalActionsCreated; }
/** {@inheritDoc} */ @Override public void onSessionEnd(CacheStoreSession ses, boolean commit) { if (ses.isWithinTransaction()) { TransactionStatus tx = ses.attach(null); if (tx != null) { try { if (commit) txMgr.commit(tx); else txMgr.rollback(tx); } catch (TransactionException e) { throw new CacheWriterException("Failed to end store session [tx=" + ses.transaction() + ']', e); } } } }
@Test public void test() { try { transactionTemplate.execute((TransactionCallback<Void>) transactionStatus -> { Tag hibernate = new Tag(); hibernate.setName("hibernate"); entityManager.persist(hibernate); Tag jpa = new Tag(); jpa.setName("jpa"); entityManager.persist(jpa); return null; }); } catch (TransactionException e) { LOGGER.error("Failure", e); } Post post = forumService.newPost("High-Performance Java Persistence", "hibernate", "jpa"); assertNotNull(post.getId()); }
@Before public void init() { try { transactionTemplate.execute((TransactionCallback<Void>) transactionStatus -> { Tag hibernate = new Tag(); hibernate.setName("hibernate"); sessionFactory.getCurrentSession().persist(hibernate); Tag jpa = new Tag(); jpa.setName("jpa"); sessionFactory.getCurrentSession().persist(jpa); return null; }); } catch (TransactionException e) { LOGGER.error("Failure", e); } }
@Override public Object beginTransaction(EntityManager entityManager, final TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException { Session session = entityManager.unwrap(Session.class); session.doWork(new Work() { @Override public void execute(Connection connection) throws SQLException { DataSourceUtils.prepareConnectionForTransaction(connection, definition); if (connection.isReadOnly() && !definition.isReadOnly()) { connection.setReadOnly(false); } } }); entityManager.getTransaction().begin(); return prepareTransaction(entityManager, definition.isReadOnly(), definition.getName()); }
@Override public RepeatStatus execute(final StepContribution contribution, final ChunkContext chunkContext) throws Exception { try { final int[] ret = this.transactionTemplate.execute(new TransactionCallback<int[]>() { @Override public int[] doInTransaction(final TransactionStatus status) { return doTask(chunkContext); } }); } catch (final TransactionException e) { log.error(e.getMessage(), e); throw e;//FAIL job status } return RepeatStatus.FINISHED; }
@POST @Path("widget2") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) //@Transactional do not work with JAX-RS default config. Review caveots with @Transactional usage (proxy requirements). //Note that SimpleJpaRepository.save is annotated with @Transactional and will use default (e.g. Propagations.REQUIRES). Illustration of deviating from default propagation. public Widget createWidgetWith(final Widget w) { try { final Widget ret = getTransactionTemplateRequiresNew().execute(new TransactionCallback<Widget>() { @Override public Widget doInTransaction(final TransactionStatus status) { return widgetRepository.save(w); } }); return ret; } catch (final TransactionException e) { log.error(whitelist(e)); throw e; } }
public static String whitelist(Exception exception) { if (exception instanceof JobInstanceAlreadyCompleteException) { return "Job instance already complete exception"; } else if (exception instanceof JsonProcessingException) { return "Json processing exception"; } else if (exception instanceof IOException) { return "IO exception"; } else if (exception instanceof TransactionException) { return "Transaction exception"; } else if (exception instanceof DataAccessException) { return "Data access exception"; } else if (exception instanceof SQLException) { return "SQL exception"; } return exception.getMessage(); }
@Override public Object beginTransaction(final EntityManager entityManager, final TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException { OpenJPAEntityManager openJpaEntityManager = getOpenJPAEntityManager(entityManager); if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { // Pass custom isolation level on to OpenJPA's JDBCFetchPlan configuration FetchPlan fetchPlan = openJpaEntityManager.getFetchPlan(); if (fetchPlan instanceof JDBCFetchPlan) { IsolationLevel isolation = IsolationLevel.fromConnectionConstant(definition.getIsolationLevel()); ((JDBCFetchPlan) fetchPlan).setIsolation(isolation); } } entityManager.getTransaction().begin(); if (!definition.isReadOnly()) { // Like with EclipseLink, make sure to start the logic transaction early so that other // participants using the connection (such as JdbcTemplate) run in a transaction. openJpaEntityManager.beginStore(); } // Custom implementation for OpenJPA savepoint handling return new OpenJpaTransactionData(openJpaEntityManager); }
/** * * {@inheritDoc} */ public void rollback( TransactionStatus status ) throws TransactionException { for ( PlatformTransactionManager dataSourceManager : _transactionManagers ) { try { dataSourceManager.rollback( ( ( (MultiTransactionStatus) status ).getTransactionStatus( dataSourceManager ) ) ); } catch( Exception ex ) { _log.error( ex.getMessage( ), ex ); } } if ( ( (MultiTransactionStatus) status ).isNewSynchonization( ) ) { TransactionSynchronizationManager.clear( ); } }
@Override public void rollback(TransactionStatus status) throws TransactionException { try{ TransactionException rollbackException = null; try{ super.rollback(status); }catch(TransactionException te){ rollbackException = te; } // 保证触发资源回滚 triggerRollback(status); if(rollbackException != null){ throw rollbackException; } }finally{ cleanup(); } }
@Override protected void doRollback(DefaultTransactionStatus status) { try{ TransactionException rollbackException = null; try{ super.doRollback(status); }catch(TransactionException te){ rollbackException = te; } // 保证触发资源回滚 triggerRollback(status); if(rollbackException != null){ throw rollbackException; } }finally{ cleanup(); } }
@Override protected Object doGetTransaction() throws TransactionException { JcrTransactionObject txObject = new JcrTransactionObject(); if (TransactionSynchronizationManager.hasResource(getSessionFactory())) { UserTxSessionHolder sessionHolder = (UserTxSessionHolder) TransactionSynchronizationManager .getResource(getSessionFactory()); if (LOG.isDebugEnabled()) { LOG.debug("Found thread-bound session [" + sessionHolder.getSession() + "] for JCR transaction"); } txObject.setSessionHolder(sessionHolder, false); } return txObject; }
void handleWaitingTickets() { Map<Boolean, List<Event>> activeEvents = eventManager.getActiveEvents().stream() .collect(Collectors.partitioningBy(this::isWaitingListFormEnabled)); activeEvents.get(true).forEach(event -> { TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW)); try { ticketReservationManager.revertTicketsToFreeIfAccessRestricted(event.getId()); distributeAvailableSeats(event); transactionManager.commit(transaction); } catch(Exception ex) { if(!(ex instanceof TransactionException)) { transactionManager.rollback(transaction); } log.error("cannot process waiting queue for event {}", event.getShortName(), ex); } }); activeEvents.get(false).forEach(eventManager::resetReleasedTickets); }
@Test public void testTransactionTimeout() { TransactionException transactionException = new TransactionTimedOutException("Transaction timeout test."); when(transactionOperations.execute(any())).thenThrow(transactionException); try { job.call(); fail("TransactionException should be thrown"); } catch (TransactionException expected) { assertSame(expected, transactionException); } verify(transactionOperations).execute(any()); verify(progress).failed(transactionException); verifyNoMoreInteractions(callable, progress, transactionOperations); }
@Override public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException { Session session = (Session) entityManager.getDelegate(); if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) { getSession(entityManager).getTransaction().setTimeout(definition.getTimeout()); } Connection connection = ((SessionImpl) session).connection(); Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(connection, definition); entityManager.getTransaction().begin(); Object transactionDataFromHibernateJpaDialect = prepareTransaction(entityManager, definition.isReadOnly(), definition.getName()); return new IsolationSupportSessionTransactionData(transactionDataFromHibernateJpaDialect, previousIsolationLevel, connection); }
@Override protected void doCommit(DefaultTransactionStatus status) throws TransactionException { HazelcastTransactionObject txObject = (HazelcastTransactionObject) status. getTransaction(); TransactionContext con = txObject.getTransactionContextHolder(). getTransactionContext(); if (status.isDebug() && log.isFinestEnabled()) { log.finest(format("Committing Hazelcast transaction on " + "TransactionContext [%s].", con)); } try { con.commitTransaction(); } catch (com.hazelcast.transaction.TransactionException ex) { throw new TransactionSystemException( "Could not commit Hazelcast transaction", ex); } }
@Override protected void doRollback(DefaultTransactionStatus status) throws TransactionException { HazelcastTransactionObject txObject = (HazelcastTransactionObject) status. getTransaction(); TransactionContext con = txObject.getTransactionContextHolder(). getTransactionContext(); if (status.isDebug() && log.isFinestEnabled()) { log.finest(format("Rolling back Hazelcast transaction on " + "TransactionContext [%s].", con)); } try { con.rollbackTransaction(); } catch (com.hazelcast.transaction.TransactionException ex) { throw new TransactionSystemException( "Could not roll back Hazelcast transaction", ex); } }
@Override protected void doCommit(DefaultTransactionStatus status) throws TransactionException { HazelcastMQTransactionObject txObject = (HazelcastMQTransactionObject) status. getTransaction(); HazelcastMQContext con = txObject.getHazelcastMQContextHolder(). getHazelcastMQContext(); if (status.isDebug() && log.isFinestEnabled()) { log.finest(format("Committing HazelcastMQ transaction on " + "HazelcastMQContext [%s].", con)); } try { con.commit(); } catch (com.hazelcast.transaction.TransactionException ex) { throw new TransactionSystemException( "Could not commit HazelcastMQ transaction", ex); } }
@Override protected void doRollback(DefaultTransactionStatus status) throws TransactionException { HazelcastMQTransactionObject txObject = (HazelcastMQTransactionObject) status. getTransaction(); HazelcastMQContext con = txObject.getHazelcastMQContextHolder(). getHazelcastMQContext(); if (status.isDebug() && log.isFinestEnabled()) { log.finest(format("Rolling back HazelcastMQ transaction on " + "HazelcastMQContext [%s].", con)); } try { con.rollback(); } catch (com.hazelcast.transaction.TransactionException ex) { throw new TransactionSystemException( "Could not rollback HazelcastMQ transaction", ex); } }
@Test public void transactionTemplateIsUsedWhenSet() { // GIVEN Mockito.when(unitDao.getAll(User.class)).thenReturn(Collections.<User>emptyList()); final boolean[] transactionTemplateUsed = {false}; TransactionTemplate transactionTemplate = new TransactionTemplate() { @Override public <T> T execute(TransactionCallback<T> action) throws TransactionException { transactionTemplateUsed[0] = true; return action.doInTransaction(null); } }; // WHEN JixtureAssert.assertThat(User.class).usingTransactionTemplate(transactionTemplate).isEmpty(); // THEN assertThat(transactionTemplateUsed[0]).isTrue(); }
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { if (readOnly) { TransactionDefinition readOnlyTransactionDefinition = new ReadOnlyTransactionDefinition( definition); return platformTransactionManager .getTransaction(readOnlyTransactionDefinition); } else { return platformTransactionManager.getTransaction(definition); } }
/** * This implementation of commit handles participating in existing * transactions and programmatic rollback requests. * Delegates to {@code isRollbackOnly}, {@code doCommit} * and {@code rollback}. * @see org.springframework.transaction.TransactionStatus#isRollbackOnly() * @see #doCommit * @see #rollback */ @Override public final void commit(TransactionStatus status) throws TransactionException { if (status.isCompleted()) { throw new IllegalTransactionStateException( "Transaction is already completed - do not call commit or rollback more than once per transaction"); } DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status; if (defStatus.isLocalRollbackOnly()) { if (defStatus.isDebug()) { logger.debug("Transactional code has requested rollback"); } processRollback(defStatus); return; } if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) { if (defStatus.isDebug()) { logger.debug("Global transaction is marked as rollback-only but transactional code requested commit"); } processRollback(defStatus); // Throw UnexpectedRollbackException only at outermost transaction boundary // or if explicitly asked to. if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) { throw new UnexpectedRollbackException( "Transaction rolled back because it has been marked as rollback-only"); } return; } processCommit(defStatus); }
/** * This implementation of rollback handles participating in existing * transactions. Delegates to {@code doRollback} and * {@code doSetRollbackOnly}. * @see #doRollback * @see #doSetRollbackOnly */ @Override public final void rollback(TransactionStatus status) throws TransactionException { if (status.isCompleted()) { throw new IllegalTransactionStateException( "Transaction is already completed - do not call commit or rollback more than once per transaction"); } DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status; processRollback(defStatus); }
/** * Invoke {@code doRollback}, handling rollback exceptions properly. * @param status object representing the transaction * @param ex the thrown application exception or error * @throws TransactionException in case of rollback failure * @see #doRollback */ private void doRollbackOnCommitException(DefaultTransactionStatus status, Throwable ex) throws TransactionException { try { if (status.isNewTransaction()) { if (status.isDebug()) { logger.debug("Initiating transaction rollback after commit exception", ex); } doRollback(status); } else if (status.hasTransaction() && isGlobalRollbackOnParticipationFailure()) { if (status.isDebug()) { logger.debug("Marking existing transaction as rollback-only after commit exception", ex); } doSetRollbackOnly(status); } } catch (RuntimeException rbex) { logger.error("Commit exception overridden by rollback exception", ex); triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN); throw rbex; } catch (Error rberr) { logger.error("Commit exception overridden by rollback exception", ex); triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN); throw rberr; } triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK); }
/** * Roll back to the savepoint that is held for the transaction. */ public void rollbackToHeldSavepoint() throws TransactionException { if (!hasSavepoint()) { throw new TransactionUsageException("No savepoint associated with current transaction"); } getSavepointManager().rollbackToSavepoint(getSavepoint()); setSavepoint(null); }