List of usage examples for org.springframework.transaction.support DefaultTransactionStatus getTransaction
public Object getTransaction()
From source file:com.newmainsoftech.spray.slingong.datastore.Slim3PlatformTransactionManagerTest.java
/** * @param transactionCommited: true when committed. false for not committed, but it's not for verifying * roll back./* ww w . j a v a 2 s . co m*/ */ protected void verifyCommitProcess(boolean transactionCommited) { /* Mockito cannot spy on "final" method because it cannot mock "final" method: * @see http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#13 mockedSlim3TxMangerInOrder.verify( slim3PlatformTransactionManager, Mockito.times( 1)) .commit( transactionStatusArgumentCaptor.capture()); */ // protected boolean shouldCommitOnGlobalRollbackOnly() // private void processCommit(DefaultTransactionStatus status) // protected void prepareForCommit(DefaultTransactionStatus status) // protected final void triggerBeforeCommit(DefaultTransactionStatus status) // protected final void triggerBeforeCompletion(DefaultTransactionStatus status) // If it's not new transaction (means not outer most transaction), then call public final boolean isFailEarlyOnGlobalRollbackOnly() ArgumentCaptor<DefaultTransactionStatus> defaultTransactionStatusArgumentCaptor = ArgumentCaptor .forClass(DefaultTransactionStatus.class); if (transactionCommited) { mockedSlim3TxMangerInOrder.verify(slim3PlatformTransactionManager, Mockito.times(1)) .doCommit(defaultTransactionStatusArgumentCaptor.capture()); DefaultTransactionStatus defaultTransactionStatus = (DefaultTransactionStatus) (defaultTransactionStatusArgumentCaptor .getValue()); Assert.assertTrue(defaultTransactionStatus.isCompleted()); // should be true since actually commit has already finished Assert.assertTrue(defaultTransactionStatus.isNewTransaction()); Assert.assertTrue(defaultTransactionStatus.hasTransaction()); Assert.assertTrue(defaultTransactionStatus.getTransaction() instanceof GlobalTransaction); ArgumentCaptor<GlobalTransaction> globalTransactionArgumentCaptor = ArgumentCaptor .forClass(GlobalTransaction.class); mockedSlim3TxMangerInOrder.verify(slim3PlatformTransactionManager, Mockito.times(1)) .getGlobalTransactionStates(globalTransactionArgumentCaptor.capture()); GlobalTransaction gtx = globalTransactionArgumentCaptor.getValue(); Assert.assertTrue(gtx instanceof GlobalTransaction); } else { mockedSlim3TxMangerInOrder.verify(slim3PlatformTransactionManager, Mockito.never()) .doCommit(defaultTransactionStatusArgumentCaptor.capture()); } // private void triggerAfterCommit(DefaultTransactionStatus status) // private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus) // private void cleanupAfterCompletion(DefaultTransactionStatus status) // protected void doCleanupAfterCompletion(Object transaction) }
From source file:com.newmainsoftech.spray.slingong.datastore.Slim3PlatformTransactionManager.java
@Override protected void doRollback(DefaultTransactionStatus defaultTransactionStatus) throws TransactionException { // Sanity check on precondition ----------------------------------------------------------- /* When logic flow got here, it should be not the case of participating existing transaction that * means the target method is the outer most transactional method what began a transaction process * at the first, and that also means newTransaction boolean member field of DefaultTransactionStatus * object should be true./* ww w . j ava 2 s .c om*/ */ if (!defaultTransactionStatus.isNewTransaction()) { // Could be caused by unaware code change on org.springframework.transaction.support.AbstractPlatformTransactionManager throw new TransactionSystemException(String.format( "Unexpected system state: attempting to roll back from participation of an " + "existing transaction (of which GlobalTransacion Id is %1$s).", ((defaultTransactionStatus.getTransaction() instanceof GlobalTransaction) ? ((GlobalTransaction) defaultTransactionStatus.getTransaction()).getId() : "null"))); } // ---------------------------------------------------------------------------------------- // Check on GlobalTransaction instance ---------------------------------------------------- GlobalTransaction gtx = (GlobalTransaction) defaultTransactionStatus.getTransaction(); Set<GlobalTransactionState> gtxStateSet = getGlobalTransactionStates(gtx); if (!gtxStateSet.contains(GlobalTransactionState.GlobalTransactionInstance)) { throw new TransactionSystemException( "Inconsistent status: defaultTransactionStatus argument is not holding " + "GlobalTransaction instance."); } String gtxIdStr = gtx.getId(); Map<String, Slim3GlobalTransactionObject> slim3GtxObjMap = slim3GtxObjMapThreadLocal.get(); Slim3GlobalTransactionObject slim3GtxObj = slim3GtxObjMap.get(gtxIdStr); if (slim3GtxObj == null) { if (logger.isErrorEnabled()) { logger.error(String.format("Encountered inconsistent status: GlobalTransaction instance (ID:%1$s) " + "held by defaultTransactionStatus argument is not among ones managed " + "by %2$s.", gtxIdStr, this.getClass().getName())); } } if (!gtxStateSet.contains(GlobalTransactionState.ActiveGlobalTransaction)) { /* Reminder: gtx here can be inactive by the ConcurrentModificationException case. * However, it's not 100% certain that, in ConcurrentModificationException case, * gtx here will be always inactive. */ slim3GtxObjMapThreadLocal.get().remove(gtxIdStr); if (logger.isWarnEnabled()) { logger.warn(String.format("Skipping to perform roll back on GlobalTransaction (ID:%1$s) since " + "it has been already in inactive state.", gtxIdStr)); } return; } if (!(gtxStateSet.contains(GlobalTransactionState.CurrentGlobalTransaction))) { /* Changed from throwing TransactionSystemException to logging incident in order to * avoid leaving GlobalTransaction instance active as much as possible by proceeding further. */ GlobalTransaction currentGtx = Datastore.getCurrentGlobalTransaction(); if (logger.isErrorEnabled()) { logger.error(String.format( "Encountered inconsistent status: GlobalTransaction object (ID:%1$s) held " + "by defaultTransactionStatus argument is not current active GlobalTransaction " + "instance (ID:%2$s).", gtxIdStr, ((currentGtx instanceof GlobalTransaction) ? currentGtx.getId() : "null"))); } } // ---------------------------------------------------------------------------------------- try { if (logger.isInfoEnabled()) { logger.info(String.format("Rolling back on Slim3 GlobalTransaction (ID:%1$s)", gtxIdStr)); } /* Note: There are the cases that GlobalTransaction instance has already been rolled back by * Slim3 behind scene of Spring transaction framework when commit failed and GlobalTransaction * instance remains active state. Even the control flow reached in those cases, there should be * no harm being made by rolling back here again. */ gtx.rollback(); } catch (Throwable throwable) { String message = String.format("Rolling back on Slim3 GlobalTransaction (ID:%1$s) failed.", gtxIdStr); throw new TransactionSystemException(message, throwable); } finally { slim3GtxObjMapThreadLocal.get().remove(gtxIdStr); /* Not necessary to call defaultTransactionStatus.setCompleted method in this block because * it will be called later in cleanupAfterCompletion method. defaultTransactionStatus.setCompleted(); */ if (gtx.isActive()) { if (logger.isErrorEnabled()) { logger.error(String.format("Slim3 GlobalTransaction (ID:%1$s) remains active " + "after the attempt of rolling back.", gtxIdStr)); } } } }
From source file:com.newmainsoftech.spray.slingong.datastore.Slim3PlatformTransactionManager.java
@Override protected void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException { String message = String.format("Setting roll-back-only flag(s) up:"); /*/*from w w w .j a va 2 s. co m*/ * Set AbstractTransactionStatus's rollbackOnly member field to true * what will make DefaultTransactionStatus's isLocalRollbackOnly method * returns true. AbstractPlatformTransactionManager's commit method * initiate roll back when its isLocalRollbackOnly method returns true. * * However, the analysis of the AbstractPlatformTransactionManager's * logic flow makes me doubt calling this method will never occurs: * * About the case called by processRollback method (that will be called * by commit method): commit method calls processRollback method when * DefaultTransactionStatus's isLocalRollbackOnly method returns true. * DefaultTransactionStatus's isLocalRollbackOnly method is also called by * processRollback method, in order for participating transaction to set * rollbackOnly member field what is done by calling this * doSetRollbackOnly method. Hence, it doesn't make much sense for this * case since, in that logic only, this will never be called. * * About the case called by doRollbackOnCommitException method (that * will be called by processRollback method): When it's participating * transaction and globalRollbackOnParticipationFailure flag value is * true, then this method is called by doRollbackOnCommitException * method. The default value of globalRollbackOnParticipationFailure * flag is true what means that the transaction originator cannot make * the transaction commit anymore once the transaction marked globally * as rollback-only. However, doRollbackOnCommitException method is * called by processCommit method and, according to Spring's * AbstractPlatformTransactionManager document (@see * http://static.springsource * .org/spring/docs/current/api/org/springframework * /transaction/support/AbstractPlatformTransactionManager * .html#setRollbackOnCommitFailure%28boolean%29) the roll back on * commit failure typically not necessary and thus to be avoided, as it * can potentially override the commit exception with a subsequent * rollback exception. I would take this as it means rather * intentionally initiating roll back after recognizing commit failure * is the recommended way than letting Spring automatically roll back * after commit failure, however it does not make sense since, because * commit is automatically handled by Spring, how it can know when and * how to roll back. It should be automatically rolled back by Spring * when failure occurs on the commit that Spring automatically performs. */ status.setRollbackOnly(); message = message + String.format("%n%tDefaultTransactionStatus object is marked as roll-back-only."); GlobalTransaction gtx = (GlobalTransaction) status.getTransaction(); if (gtx instanceof GlobalTransaction) { String gtxIdStr = gtx.getId(); Slim3GlobalTransactionObject slim3GtxObj = slim3GtxObjMapThreadLocal.get().get(gtxIdStr); if (slim3GtxObj != null) { slim3GtxObj.setRollbackOnly(true); slim3GtxObjMapThreadLocal.get().put(gtxIdStr, slim3GtxObj); message = message + String .format("%n%tSlim3GlobalTransactionObject object for GlobalTransaction instance (ID:%1$s) " + "is marked as roll-back-only.", gtxIdStr); } else { if (logger.isWarnEnabled()) { logger.warn( String.format("Inconsistent system state: GlobalTransaction instance (ID:%1$s) held " + "by state DefaultTransactionStatus argument is not among ones managed " + "by %2$s.", gtxIdStr, this.getClass().getName())); } } } if (logger.isInfoEnabled()) logger.info(message); }
From source file:org.fcrepo.camel.FcrepoProducer.java
/** * Define how message exchanges are processed. * * @param exchange the InOut message exchange * @throws FcrepoOperationFailedException when the underlying HTTP request results in an error */// ww w . ja v a2s. co m @Override public void process(final Exchange exchange) throws FcrepoOperationFailedException { if (exchange.isTransacted()) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(final TransactionStatus status) { final DefaultTransactionStatus st = (DefaultTransactionStatus) status; final FcrepoTransactionObject tx = (FcrepoTransactionObject) st.getTransaction(); try { doRequest(exchange, tx.getSessionId()); } catch (final FcrepoOperationFailedException ex) { throw new TransactionSystemException("Error executing fcrepo request in transaction: ", ex); } } }); } else { doRequest(exchange, null); } }
From source file:org.springframework.batch.core.step.item.FaultTolerantStepFactoryBeanUnexpectedRollbackTests.java
@Test @Ignore //FIXME/*from ww w . j a v a 2s . c o m*/ public void testTransactionException() throws Exception { final SkipWriterStub<String> writer = new SkipWriterStub<String>(); FaultTolerantStepFactoryBean<String, String> factory = new FaultTolerantStepFactoryBean<String, String>(); factory.setItemWriter(writer); @SuppressWarnings("serial") DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource) { private boolean failed = false; @Override protected void doCommit(DefaultTransactionStatus status) throws TransactionException { if (writer.getWritten().isEmpty() || failed || !isExistingTransaction(status.getTransaction())) { super.doCommit(status); return; } failed = true; status.setRollbackOnly(); super.doRollback(status); throw new UnexpectedRollbackException("Planned"); } }; factory.setBeanName("stepName"); factory.setTransactionManager(transactionManager); factory.setCommitInterval(2); ItemReader<String> reader = new ListItemReader<String>(Arrays.asList("1", "2")); factory.setItemReader(reader); JobRepositoryFactoryBean repositoryFactory = new JobRepositoryFactoryBean(); repositoryFactory.setDataSource(dataSource); repositoryFactory.setTransactionManager(transactionManager); repositoryFactory.afterPropertiesSet(); JobRepository repository = repositoryFactory.getObject(); factory.setJobRepository(repository); JobExecution jobExecution = repository.createJobExecution("job", new JobParameters()); StepExecution stepExecution = jobExecution.createStepExecution(factory.getName()); repository.add(stepExecution); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals("[]", writer.getCommitted().toString()); }
From source file:org.springframework.transaction.compensating.support.AbstractCompensatingTransactionManagerDelegate.java
public void doCommit(DefaultTransactionStatus status) throws TransactionException { CompensatingTransactionObject txObject = (CompensatingTransactionObject) status.getTransaction(); txObject.getHolder().getTransactionOperationManager().commit(); }
From source file:org.springframework.transaction.compensating.support.AbstractCompensatingTransactionManagerDelegate.java
public void doRollback(DefaultTransactionStatus status) throws TransactionException { CompensatingTransactionObject txObject = (CompensatingTransactionObject) status.getTransaction(); txObject.getHolder().getTransactionOperationManager().rollback(); }
From source file:org.springframework.transaction.support.AbstractPlatformTransactionManager.java
/** * Trigger {@code afterCompletion} callbacks. * @param status object representing the transaction * @param completionStatus completion status according to TransactionSynchronization constants *//* w w w. ja v a2s .co m*/ 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); } } }
From source file:org.springframework.transaction.support.AbstractPlatformTransactionManager.java
/** * Clean up after completion, clearing synchronization if necessary, * and invoking doCleanupAfterCompletion. * @param status object representing the transaction * @see #doCleanupAfterCompletion// ww w . ja v a2s .co m */ 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()); } }