Example usage for org.springframework.transaction TransactionDefinition PROPAGATION_REQUIRED

List of usage examples for org.springframework.transaction TransactionDefinition PROPAGATION_REQUIRED

Introduction

In this page you can find the example usage for org.springframework.transaction TransactionDefinition PROPAGATION_REQUIRED.

Prototype

int PROPAGATION_REQUIRED

To view the source code for org.springframework.transaction TransactionDefinition PROPAGATION_REQUIRED.

Click Source Link

Document

Support a current transaction; create a new one if none exists.

Usage

From source file:org.sparkcommerce.core.order.service.OrderServiceImpl.java

@Override
public Order save(Order order, Boolean priceOrder) throws PricingException {
    //persist the order first
    TransactionStatus status = TransactionUtils.createTransaction("saveOrder",
            TransactionDefinition.PROPAGATION_REQUIRED, transactionManager);
    try {/*  w  ww .java 2s . com*/
        order = persist(order);
        TransactionUtils.finalizeTransaction(status, transactionManager, false);
    } catch (RuntimeException ex) {
        TransactionUtils.finalizeTransaction(status, transactionManager, true);
        throw ex;
    }

    //make any pricing changes - possibly retrying with the persisted state if there's a lock failure
    if (priceOrder) {
        int retryCount = 0;
        boolean isValid = false;
        while (!isValid) {
            try {
                order = pricingService.executePricing(order);
                isValid = true;
            } catch (Exception ex) {
                boolean isValidCause = false;
                Throwable cause = ex;
                while (!isValidCause) {
                    if (cause.getClass().equals(LockAcquisitionException.class)) {
                        isValidCause = true;
                    }
                    cause = cause.getCause();
                    if (cause == null) {
                        break;
                    }
                }
                if (isValidCause) {
                    if (LOG.isInfoEnabled()) {
                        LOG.info("Problem acquiring lock during pricing call - attempting to price again.");
                    }
                    isValid = false;
                    if (retryCount >= pricingRetryCountForLockFailure) {
                        if (LOG.isInfoEnabled()) {
                            LOG.info("Problem acquiring lock during pricing call. Retry limit exceeded at ("
                                    + retryCount + "). Throwing exception.");
                        }
                        if (ex instanceof PricingException) {
                            throw (PricingException) ex;
                        } else {
                            throw new PricingException(ex);
                        }
                    } else {
                        order = findOrderById(order.getId());
                        retryCount++;
                    }
                    try {
                        Thread.sleep(pricingRetryWaitIntervalForLockFailure);
                    } catch (Throwable e) {
                        //do nothing
                    }
                } else {
                    if (ex instanceof PricingException) {
                        throw (PricingException) ex;
                    } else {
                        throw new PricingException(ex);
                    }
                }
            }
        }

        //make the final save of the priced order
        status = TransactionUtils.createTransaction("saveOrder", TransactionDefinition.PROPAGATION_REQUIRED,
                transactionManager);
        try {
            order = persist(order);
            TransactionUtils.finalizeTransaction(status, transactionManager, false);
        } catch (RuntimeException ex) {
            TransactionUtils.finalizeTransaction(status, transactionManager, true);
            throw ex;
        }
    }

    return order;
}

From source file:org.springframework.integration.jdbc.store.channel.AbstractTxTimeoutMessageStoreTests.java

public void test() throws InterruptedException {

    int maxMessages = 10;
    int maxWaitTime = 30000;

    final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);

    transactionTemplate.setIsolationLevel(Isolation.READ_COMMITTED.value());
    transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

    for (int i = 1; i <= maxMessages; ++i) {
        final String message = "TEST MESSAGE " + i;
        log.info("Sending message: " + message);

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override//from w w w  .  j av a 2 s  . c om
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                inputChannel.send(MessageBuilder.withPayload(message).build());
            }
        });

        log.info(String.format("Done sending message %s of %s: %s", i, maxMessages, message));
    }

    log.info("Done sending " + maxMessages + " messages.");

    Assert.assertTrue(String.format("Contdown latch did not count down from " + "%s to 0 in %sms.", maxMessages,
            maxWaitTime), testService.await(maxWaitTime));

    Thread.sleep(2000);

    Assert.assertEquals(Integer.valueOf(0), Integer.valueOf(jdbcChannelMessageStore.getSizeOfIdCache()));
    Assert.assertEquals(Integer.valueOf(maxMessages), Integer.valueOf(testService.getSeenMessages().size()));
    Assert.assertEquals(Integer.valueOf(0), Integer.valueOf(testService.getDuplicateMessagesCount()));
}

From source file:org.springframework.test.context.jdbc.DatabaseInitializerTestExecutionListener.java

/**
 * Execute the SQL scripts configured via the supplied
 * {@link DatabaseInitializer @DatabaseInitializer} for the given
 * {@link ExecutionPhase} and {@link TestContext}.
 *
 * <p>Special care must be taken in order to properly support the
 * {@link DatabaseInitializer#requireNewTransaction requireNewTransaction}
 * flag./*from w  w w.  ja  v  a2  s  .  c o m*/
 *
 * @param databaseInitializer the {@code @DatabaseInitializer} to parse
 * @param executionPhase the current execution phase
 * @param testContext the current {@code TestContext}
 * @param classLevel {@code true} if {@link DatabaseInitializer @DatabaseInitializer}
 * was declared at the class level
 */
@SuppressWarnings("serial")
private void executeDatabaseInitializer(DatabaseInitializer databaseInitializer, ExecutionPhase executionPhase,
        TestContext testContext, boolean classLevel) throws Exception {
    if (logger.isDebugEnabled()) {
        logger.debug(String.format("Processing %s for execution phase [%s] and test context %s.",
                databaseInitializer, executionPhase, testContext));
    }

    if (executionPhase != databaseInitializer.executionPhase()) {
        return;
    }

    final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
    populator.setSqlScriptEncoding(databaseInitializer.encoding());
    populator.setSeparator(databaseInitializer.separator());
    populator.setCommentPrefix(databaseInitializer.commentPrefix());
    populator.setBlockCommentStartDelimiter(databaseInitializer.blockCommentStartDelimiter());
    populator.setBlockCommentEndDelimiter(databaseInitializer.blockCommentEndDelimiter());
    populator.setContinueOnError(databaseInitializer.continueOnError());
    populator.setIgnoreFailedDrops(databaseInitializer.ignoreFailedDrops());

    String[] scripts = getScripts(databaseInitializer, testContext, classLevel);
    scripts = TestContextResourceUtils.convertToClasspathResourcePaths(testContext.getTestClass(), scripts);
    populator.setScripts(
            TestContextResourceUtils.convertToResources(testContext.getApplicationContext(), scripts));
    if (logger.isDebugEnabled()) {
        logger.debug("Executing SQL scripts: " + ObjectUtils.nullSafeToString(scripts));
    }

    final DataSource dataSource = TestContextTransactionUtils.retrieveDataSource(testContext,
            databaseInitializer.dataSource());
    final PlatformTransactionManager transactionManager = TestContextTransactionUtils
            .retrieveTransactionManager(testContext, databaseInitializer.transactionManager());

    int propagation = databaseInitializer.requireNewTransaction()
            ? TransactionDefinition.PROPAGATION_REQUIRES_NEW
            : TransactionDefinition.PROPAGATION_REQUIRED;

    TransactionAttribute transactionAttribute = TestContextTransactionUtils
            .createDelegatingTransactionAttribute(testContext, new DefaultTransactionAttribute(propagation));

    new TransactionTemplate(transactionManager, transactionAttribute)
            .execute(new TransactionCallbackWithoutResult() {

                @Override
                public void doInTransactionWithoutResult(TransactionStatus status) {
                    populator.execute(dataSource);
                };
            });
}

From source file:org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener.java

/**
 * Execute the SQL scripts configured via the supplied {@link Sql @Sql}
 * annotation for the given {@link ExecutionPhase} and {@link TestContext}.
 * <p>Special care must be taken in order to properly support the configured
 * {@link SqlConfig#transactionMode}./*from   w  w  w.j av  a2 s.  co m*/
 * @param sql the {@code @Sql} annotation to parse
 * @param executionPhase the current execution phase
 * @param testContext the current {@code TestContext}
 * @param classLevel {@code true} if {@link Sql @Sql} was declared at the class level
 */
private void executeSqlScripts(Sql sql, ExecutionPhase executionPhase, TestContext testContext,
        boolean classLevel) throws Exception {

    if (executionPhase != sql.executionPhase()) {
        return;
    }

    MergedSqlConfig mergedSqlConfig = new MergedSqlConfig(sql.config(), testContext.getTestClass());
    if (logger.isDebugEnabled()) {
        logger.debug(String.format("Processing %s for execution phase [%s] and test context %s.",
                mergedSqlConfig, executionPhase, testContext));
    }

    final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
    populator.setSqlScriptEncoding(mergedSqlConfig.getEncoding());
    populator.setSeparator(mergedSqlConfig.getSeparator());
    populator.setCommentPrefix(mergedSqlConfig.getCommentPrefix());
    populator.setBlockCommentStartDelimiter(mergedSqlConfig.getBlockCommentStartDelimiter());
    populator.setBlockCommentEndDelimiter(mergedSqlConfig.getBlockCommentEndDelimiter());
    populator.setContinueOnError(mergedSqlConfig.getErrorMode() == ErrorMode.CONTINUE_ON_ERROR);
    populator.setIgnoreFailedDrops(mergedSqlConfig.getErrorMode() == ErrorMode.IGNORE_FAILED_DROPS);

    String[] scripts = getScripts(sql, testContext, classLevel);
    scripts = TestContextResourceUtils.convertToClasspathResourcePaths(testContext.getTestClass(), scripts);
    List<Resource> scriptResources = TestContextResourceUtils
            .convertToResourceList(testContext.getApplicationContext(), scripts);
    for (String stmt : sql.statements()) {
        if (StringUtils.hasText(stmt)) {
            stmt = stmt.trim();
            scriptResources.add(new ByteArrayResource(stmt.getBytes(), "from inlined SQL statement: " + stmt));
        }
    }
    populator.setScripts(scriptResources.toArray(new Resource[scriptResources.size()]));
    if (logger.isDebugEnabled()) {
        logger.debug("Executing SQL scripts: " + ObjectUtils.nullSafeToString(scriptResources));
    }

    String dsName = mergedSqlConfig.getDataSource();
    String tmName = mergedSqlConfig.getTransactionManager();
    DataSource dataSource = TestContextTransactionUtils.retrieveDataSource(testContext, dsName);
    PlatformTransactionManager txMgr = TestContextTransactionUtils.retrieveTransactionManager(testContext,
            tmName);
    boolean newTxRequired = (mergedSqlConfig.getTransactionMode() == TransactionMode.ISOLATED);

    if (txMgr == null) {
        Assert.state(!newTxRequired,
                () -> String.format(
                        "Failed to execute SQL scripts for test context %s: "
                                + "cannot execute SQL scripts using Transaction Mode "
                                + "[%s] without a PlatformTransactionManager.",
                        testContext, TransactionMode.ISOLATED));
        Assert.state(dataSource != null,
                () -> String.format("Failed to execute SQL scripts for test context %s: "
                        + "supply at least a DataSource or PlatformTransactionManager.", testContext));
        // Execute scripts directly against the DataSource
        populator.execute(dataSource);
    } else {
        DataSource dataSourceFromTxMgr = getDataSourceFromTransactionManager(txMgr);
        // Ensure user configured an appropriate DataSource/TransactionManager pair.
        if (dataSource != null && dataSourceFromTxMgr != null && !dataSource.equals(dataSourceFromTxMgr)) {
            throw new IllegalStateException(String.format(
                    "Failed to execute SQL scripts for test context %s: "
                            + "the configured DataSource [%s] (named '%s') is not the one associated with "
                            + "transaction manager [%s] (named '%s').",
                    testContext, dataSource.getClass().getName(), dsName, txMgr.getClass().getName(), tmName));
        }
        if (dataSource == null) {
            dataSource = dataSourceFromTxMgr;
            Assert.state(dataSource != null, () -> String.format("Failed to execute SQL scripts for "
                    + "test context %s: could not obtain DataSource from transaction manager [%s] (named '%s').",
                    testContext, txMgr.getClass().getName(), tmName));
        }
        final DataSource finalDataSource = dataSource;
        int propagation = (newTxRequired ? TransactionDefinition.PROPAGATION_REQUIRES_NEW
                : TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionAttribute txAttr = TestContextTransactionUtils.createDelegatingTransactionAttribute(
                testContext, new DefaultTransactionAttribute(propagation));
        new TransactionTemplate(txMgr, txAttr).execute(status -> {
            populator.execute(finalDataSource);
            return null;
        });
    }
}

From source file:org.springframework.transaction.reactive.AbstractReactiveTransactionManager.java

/**
 * This implementation handles propagation behavior. Delegates to
 * {@code doGetTransaction}, {@code isExistingTransaction}
 * and {@code doBegin}./*from w ww .j a v  a 2s .co  m*/
 * @see #doGetTransaction
 * @see #isExistingTransaction
 * @see #doBegin
 */
@Override
public final Mono<ReactiveTransaction> getReactiveTransaction(@Nullable TransactionDefinition definition)
        throws TransactionException {

    // Use defaults if no transaction definition given.
    TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());

    return TransactionSynchronizationManager.currentTransaction().flatMap(synchronizationManager -> {

        Object transaction = doGetTransaction(synchronizationManager);

        // Cache debug flag to avoid repeated checks.
        boolean debugEnabled = logger.isDebugEnabled();

        if (isExistingTransaction(transaction)) {
            // Existing transaction found -> check propagation behavior to find out how to behave.
            return handleExistingTransaction(synchronizationManager, def, transaction, debugEnabled);
        }

        // Check definition settings for new transaction.
        if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
            return Mono.error(new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout()));
        }

        // No existing transaction found -> check propagation behavior to find out how to proceed.
        if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
            return Mono.error(new IllegalTransactionStateException(
                    "No existing transaction found for transaction marked with propagation 'mandatory'"));
        } else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED
                || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW
                || def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {

            return TransactionContextManager.currentContext().map(TransactionSynchronizationManager::new)
                    .flatMap(nestedSynchronizationManager -> suspend(nestedSynchronizationManager, null)
                            .map(Optional::of).defaultIfEmpty(Optional.empty()).flatMap(suspendedResources -> {
                                if (debugEnabled) {
                                    logger.debug("Creating new transaction with name [" + def.getName() + "]: "
                                            + def);
                                }
                                return Mono.defer(() -> {
                                    GenericReactiveTransaction status = newReactiveTransaction(
                                            nestedSynchronizationManager, def, transaction, true, debugEnabled,
                                            suspendedResources.orElse(null));
                                    return doBegin(nestedSynchronizationManager, transaction, def)
                                            .doOnSuccess(ignore -> prepareSynchronization(
                                                    nestedSynchronizationManager, status, def))
                                            .thenReturn(status);
                                }).onErrorResume(ErrorPredicates.RUNTIME_OR_ERROR,
                                        ex -> resume(nestedSynchronizationManager, null,
                                                suspendedResources.orElse(null)).then(Mono.error(ex)));
                            }));
        } else {
            // Create "empty" transaction: no actual transaction, but potentially synchronization.
            if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
                logger.warn("Custom isolation level specified but no actual transaction initiated; "
                        + "isolation level will effectively be ignored: " + def);
            }
            return Mono.just(
                    prepareReactiveTransaction(synchronizationManager, def, null, true, debugEnabled, null));
        }
    });
}

From source file:org.springframework.transaction.support.AbstractPlatformTransactionManager.java

/**
 * This implementation handles propagation behavior. Delegates to
 * {@code doGetTransaction}, {@code isExistingTransaction}
 * and {@code doBegin}.//from w w  w .  ja va  2 s . c o  m
 * @see #doGetTransaction
 * @see #isExistingTransaction
 * @see #doBegin
 */
@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
        throws TransactionException {
    Object transaction = doGetTransaction();

    // Cache debug flag to avoid repeated checks.
    boolean debugEnabled = logger.isDebugEnabled();

    if (definition == null) {
        // Use defaults if no transaction definition given.
        definition = new DefaultTransactionDefinition();
    }

    if (isExistingTransaction(transaction)) {
        // Existing transaction found -> check propagation behavior to find out how to behave.
        return handleExistingTransaction(definition, transaction, debugEnabled);
    }

    // Check definition settings for new transaction.
    if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
        throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
    }

    // No existing transaction found -> check propagation behavior to find out how to proceed.
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
        throw new IllegalTransactionStateException(
                "No existing transaction found for transaction marked with propagation 'mandatory'");
    } else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED
            || definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW
            || definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        SuspendedResourcesHolder suspendedResources = suspend(null);
        if (debugEnabled) {
            logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
        }
        try {
            boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
            DefaultTransactionStatus status = newTransactionStatus(definition, transaction, true,
                    newSynchronization, debugEnabled, suspendedResources);
            doBegin(transaction, definition);
            prepareSynchronization(status, definition);
            return status;
        } catch (RuntimeException | Error ex) {
            resume(null, suspendedResources);
            throw ex;
        }
    } else {
        // Create "empty" transaction: no actual transaction, but potentially synchronization.
        if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT
                && logger.isWarnEnabled()) {
            logger.warn("Custom isolation level specified but no actual transaction initiated; "
                    + "isolation level will effectively be ignored: " + definition);
        }
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
    }
}

From source file:org.unitils.database.transaction.impl.DefaultUnitilsTransactionManager.java

/**
 * Returns a <code>TransactionDefinition</code> object containing the
 * necessary transaction parameters. Simply returns a default
 * <code>DefaultTransactionDefinition</code> object with the 'propagation
 * required' attribute/*w  ww . j av  a 2 s.  c  o m*/
 *
 * @param testObject The test object, not null
 * @return The default TransactionDefinition
 */
protected TransactionDefinition createTransactionDefinition(Object testObject) {
    return new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED);
}

From source file:se.vgregion.service.innovationsslussen.idea.IdeaServiceImpl.java

@Override
public Idea addLike(long companyId, long groupId, long userId, String urlTitle) {

    TransactionStatus transaction = transactionManager
            .getTransaction(new DefaultTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED));

    boolean isIdeaUserLiked = getIsIdeaUserLiked(companyId, groupId, userId, urlTitle);
    Idea idea = findIdeaByUrlTitle(urlTitle);

    if (isIdeaUserLiked) {
        // User already likes the idea
        return idea;
    }//  w  w  w .  ja v a  2s  . c  om

    IdeaUserLike ideaUserLike = new IdeaUserLike(companyId, groupId, userId);
    ideaUserLike.setIdea(idea);

    ideaUserLikeRepository.merge(ideaUserLike);
    ideaUserLikeRepository.flush();

    transactionManager.commit(transaction);

    return ideaRepository.find(idea.getId());
}

From source file:se.vgregion.service.innovationsslussen.idea.IdeaServiceImpl.java

private Idea upgradeIfOldVersion(Idea idea) {
    // Upgrade potentially old ideas without the hidden attribute set
    if (idea.getHidden() == null) {
        idea.setHidden(false);/*ww  w  .  j  ava  2 s. c o m*/
        TransactionStatus transaction = null;
        try {
            // Do the transaction manually since we may run this in a separate thread.
            transaction = transactionManager.getTransaction(
                    new DefaultTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED));
            // Merge here so we don't get unexpected consequences later when we will compare to decide whether
            // the idea has changed. This should not cause a change.
            ideaRepository.merge(idea);
            transactionManager.commit(transaction);
        } catch (RuntimeException e) {
            transactionManager.rollback(transaction);
        }
    }
    return idea;
}

From source file:uk.ac.ebi.phenotype.solr.indexer.AbstractIndexer.java

protected void initialiseHibernateSession(ApplicationContext applicationContext) {
    // allow hibernate session to stay open the whole execution
    PlatformTransactionManager transactionManager = (PlatformTransactionManager) applicationContext
            .getBean("transactionManager");
    DefaultTransactionAttribute transactionAttribute = new DefaultTransactionAttribute(
            TransactionDefinition.PROPAGATION_REQUIRED);
    transactionAttribute.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
    transactionManager.getTransaction(transactionAttribute);
}