/** * 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 | Error rbex) { logger.error("Commit exception overridden by rollback exception", ex); triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN); throw rbex; } triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK); }
/** * Trigger {@code afterCompletion} callbacks. * @param status object representing the transaction * @param completionStatus completion status according to TransactionSynchronization constants */ private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus) { if (status.isNewSynchronization()) { List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager.getSynchronizations(); TransactionSynchronizationManager.clearSynchronization(); if (!status.hasTransaction() || status.isNewTransaction()) { if (status.isDebug()) { logger.trace("Triggering afterCompletion synchronization"); } // No transaction or new transaction for the current scope -> // invoke the afterCompletion callbacks immediately invokeAfterCompletion(synchronizations, completionStatus); } else if (!synchronizations.isEmpty()) { // Existing transaction that we participate in, controlled outside // of the scope of this Spring transaction manager -> try to register // an afterCompletion callback with the existing (JTA) transaction. registerAfterCompletionWithExistingTransaction(status.getTransaction(), synchronizations); } } }
else if (status.isNewTransaction()) { if (status.isDebug()) { logger.debug("Initiating transaction rollback");
/** * Clean up after completion, clearing synchronization if necessary, * and invoking doCleanupAfterCompletion. * @param status object representing the transaction * @see #doCleanupAfterCompletion */ private void cleanupAfterCompletion(DefaultTransactionStatus status) { status.setCompleted(); if (status.isNewSynchronization()) { TransactionSynchronizationManager.clear(); } if (status.isNewTransaction()) { doCleanupAfterCompletion(status.getTransaction()); } if (status.getSuspendedResources() != null) { if (status.isDebug()) { logger.debug("Resuming suspended transaction after completion of inner transaction"); } Object transaction = (status.hasTransaction() ? status.getTransaction() : null); resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources()); } }
/** * 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 | Error rbex) { logger.error("Commit exception overridden by rollback exception", ex); triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN); throw rbex; } triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK); }
/** * Trigger {@code afterCompletion} callbacks. * @param status object representing the transaction * @param completionStatus completion status according to TransactionSynchronization constants */ private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus) { if (status.isNewSynchronization()) { List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager.getSynchronizations(); TransactionSynchronizationManager.clearSynchronization(); if (!status.hasTransaction() || status.isNewTransaction()) { if (status.isDebug()) { logger.trace("Triggering afterCompletion synchronization"); } // No transaction or new transaction for the current scope -> // invoke the afterCompletion callbacks immediately invokeAfterCompletion(synchronizations, completionStatus); } else if (!synchronizations.isEmpty()) { // Existing transaction that we participate in, controlled outside // of the scope of this Spring transaction manager -> try to register // an afterCompletion callback with the existing (JTA) transaction. registerAfterCompletionWithExistingTransaction(status.getTransaction(), synchronizations); } } }
@Test public void existingTransaction() { PlatformTransactionManager tm = new TestTransactionManager(true, true); DefaultTransactionStatus status1 = (DefaultTransactionStatus) tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS)); assertTrue("Must have transaction", status1.getTransaction() != null); assertTrue("Must not be new transaction", !status1.isNewTransaction()); DefaultTransactionStatus status2 = (DefaultTransactionStatus) tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED)); assertTrue("Must have transaction", status2.getTransaction() != null); assertTrue("Must not be new transaction", !status2.isNewTransaction()); try { DefaultTransactionStatus status3 = (DefaultTransactionStatus) tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_MANDATORY)); assertTrue("Must have transaction", status3.getTransaction() != null); assertTrue("Must not be new transaction", !status3.isNewTransaction()); } catch (NoTransactionException ex) { fail("Should not have thrown NoTransactionException"); } }
/** * Clean up after completion, clearing synchronization if necessary, * and invoking doCleanupAfterCompletion. * @param status object representing the transaction * @see #doCleanupAfterCompletion */ private void cleanupAfterCompletion(DefaultTransactionStatus status) { status.setCompleted(); if (status.isNewSynchronization()) { TransactionSynchronizationManager.clear(); } if (status.isNewTransaction()) { doCleanupAfterCompletion(status.getTransaction()); } if (status.getSuspendedResources() != null) { if (status.isDebug()) { logger.debug("Resuming suspended transaction after completion of inner transaction"); } Object transaction = (status.hasTransaction() ? status.getTransaction() : null); resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources()); } }
else if (status.isNewTransaction()) { if (status.isDebug()) { logger.debug("Initiating transaction rollback");
status.releaseHeldSavepoint(); else if (status.isNewTransaction()) { if (status.isDebug()) { logger.debug("Initiating transaction commit");
@Test public void noExistingTransaction() { PlatformTransactionManager tm = new TestTransactionManager(false, true); DefaultTransactionStatus status1 = (DefaultTransactionStatus) tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS)); assertFalse("Must not have transaction", status1.hasTransaction()); DefaultTransactionStatus status2 = (DefaultTransactionStatus) tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED)); assertTrue("Must have transaction", status2.hasTransaction()); assertTrue("Must be new transaction", status2.isNewTransaction()); try { tm.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_MANDATORY)); fail("Should not have thrown NoTransactionException"); } catch (IllegalTransactionStateException ex) { // expected } }
status.releaseHeldSavepoint(); else if (status.isNewTransaction()) { if (status.isDebug()) { logger.debug("Initiating transaction commit");
@Override protected void prepareForCommit(DefaultTransactionStatus status) { if (this.earlyFlushBeforeCommit && status.isNewTransaction()) { } }
protected void doRollback(DefaultTransactionStatus status) { ContextSourceAndDataSourceTransactionObject actualTransactionObject = (ContextSourceAndDataSourceTransactionObject) status .getTransaction(); super.doRollback(new DefaultTransactionStatus(actualTransactionObject .getDataSourceTransactionObject(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status .isDebug(), status.getSuspendedResources())); ldapManagerDelegate.doRollback(new DefaultTransactionStatus( actualTransactionObject.getLdapTransactionObject(), status .isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status .getSuspendedResources())); }
protected void doRollback(DefaultTransactionStatus status) { ContextSourceAndDataSourceTransactionObject actualTransactionObject = (ContextSourceAndDataSourceTransactionObject) status .getTransaction(); super.doRollback(new DefaultTransactionStatus(actualTransactionObject .getDataSourceTransactionObject(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status .isDebug(), status.getSuspendedResources())); ldapManagerDelegate.doRollback(new DefaultTransactionStatus( actualTransactionObject.getLdapTransactionObject(), status .isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status .getSuspendedResources())); }
protected void doRollback(DefaultTransactionStatus status) { ContextSourceAndHibernateTransactionObject actualTransactionObject = (ContextSourceAndHibernateTransactionObject) status .getTransaction(); super.doRollback(new DefaultTransactionStatus(actualTransactionObject .getHibernateTransactionObject(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status .isDebug(), status.getSuspendedResources())); ldapManagerDelegate.doRollback(new DefaultTransactionStatus( actualTransactionObject.getLdapTransactionObject(), status .isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status .getSuspendedResources())); }
protected void doRollback(DefaultTransactionStatus status) { ContextSourceAndHibernateTransactionObject actualTransactionObject = (ContextSourceAndHibernateTransactionObject) status .getTransaction(); super.doRollback(new DefaultTransactionStatus(actualTransactionObject .getHibernateTransactionObject(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status .isDebug(), status.getSuspendedResources())); ldapManagerDelegate.doRollback(new DefaultTransactionStatus( actualTransactionObject.getLdapTransactionObject(), status .isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status .getSuspendedResources())); }
protected void doRollback(DefaultTransactionStatus status) { ContextSourceAndHibernateTransactionObject actualTransactionObject = (ContextSourceAndHibernateTransactionObject) status .getTransaction(); super.doRollback(new DefaultTransactionStatus(actualTransactionObject .getHibernateTransactionObject(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status .isDebug(), status.getSuspendedResources())); ldapManagerDelegate.doRollback(new DefaultTransactionStatus( actualTransactionObject.getLdapTransactionObject(), status .isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status .getSuspendedResources())); }
protected void doRollback(DefaultTransactionStatus status) { ContextSourceAndDataSourceTransactionObject actualTransactionObject = (ContextSourceAndDataSourceTransactionObject) status .getTransaction(); super.doRollback(new DefaultTransactionStatus(actualTransactionObject .getDataSourceTransactionObject(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status .isDebug(), status.getSuspendedResources())); ldapManagerDelegate.doRollback(new DefaultTransactionStatus( actualTransactionObject.getLdapTransactionObject(), status .isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status .getSuspendedResources())); }
@Override protected void doSetRollbackOnly(DefaultTransactionStatus status) { MolgenisTransaction transaction = (MolgenisTransaction) status.getTransaction(); DefaultTransactionStatus jpaTransactionStatus = new DefaultTransactionStatus( transaction.getDataSourceTransaction(), status.isNewTransaction(), status.isNewSynchronization(), status.isReadOnly(), status.isDebug(), status.getSuspendedResources()); super.doSetRollbackOnly(jpaTransactionStatus); }