Search in sources :

Example 1 with TransactionAttribute

use of org.springframework.transaction.interceptor.TransactionAttribute in project spring-framework by spring-projects.

the class TransactionAspectTests method testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface.

/**
	 * Note: resolution does not occur. Thus we can't make a class transactional if
	 * it implements a transactionally annotated interface. This behavior could only
	 * be changed in AbstractFallbackTransactionAttributeSource in Spring proper.
	 * See SPR-14322.
	 */
@Test
public void testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface() throws Exception {
    AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
    Method method = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class);
    TransactionAttribute ta = atas.getTransactionAttribute(method, ImplementsAnnotatedInterface.class);
    assertNull(ta);
}
Also used : TransactionAttribute(org.springframework.transaction.interceptor.TransactionAttribute) Method(java.lang.reflect.Method) AnnotationTransactionAttributeSource(org.springframework.transaction.annotation.AnnotationTransactionAttributeSource) Test(org.junit.Test)

Example 2 with TransactionAttribute

use of org.springframework.transaction.interceptor.TransactionAttribute in project spring-framework by spring-projects.

the class SqlScriptsTestExecutionListener method executeSqlScripts.

/**
	 * 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}.
	 * @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;
        });
    }
}
Also used : TransactionAttribute(org.springframework.transaction.interceptor.TransactionAttribute) DefaultTransactionAttribute(org.springframework.transaction.interceptor.DefaultTransactionAttribute) DefaultTransactionAttribute(org.springframework.transaction.interceptor.DefaultTransactionAttribute) ResourceDatabasePopulator(org.springframework.jdbc.datasource.init.ResourceDatabasePopulator) ClassPathResource(org.springframework.core.io.ClassPathResource) ByteArrayResource(org.springframework.core.io.ByteArrayResource) Resource(org.springframework.core.io.Resource) TransactionTemplate(org.springframework.transaction.support.TransactionTemplate) ByteArrayResource(org.springframework.core.io.ByteArrayResource) PlatformTransactionManager(org.springframework.transaction.PlatformTransactionManager) DataSource(javax.sql.DataSource)

Example 3 with TransactionAttribute

use of org.springframework.transaction.interceptor.TransactionAttribute in project spring-framework by spring-projects.

the class TransactionalTestExecutionListener method beforeTestMethod.

/**
	 * If the test method of the supplied {@linkplain TestContext test context}
	 * is configured to run within a transaction, this method will run
	 * {@link BeforeTransaction @BeforeTransaction} methods and start a new
	 * transaction.
	 * <p>Note that if a {@code @BeforeTransaction} method fails, any remaining
	 * {@code @BeforeTransaction} methods will not be invoked, and a transaction
	 * will not be started.
	 * @see org.springframework.transaction.annotation.Transactional
	 * @see #getTransactionManager(TestContext, String)
	 */
@Override
public void beforeTestMethod(final TestContext testContext) throws Exception {
    final Method testMethod = testContext.getTestMethod();
    final Class<?> testClass = testContext.getTestClass();
    Assert.notNull(testMethod, "The test method of the supplied TestContext must not be null");
    TransactionContext txContext = TransactionContextHolder.removeCurrentTransactionContext();
    Assert.state(txContext == null, "Cannot start a new transaction without ending the existing transaction.");
    PlatformTransactionManager tm = null;
    TransactionAttribute transactionAttribute = this.attributeSource.getTransactionAttribute(testMethod, testClass);
    if (transactionAttribute != null) {
        transactionAttribute = TestContextTransactionUtils.createDelegatingTransactionAttribute(testContext, transactionAttribute);
        if (logger.isDebugEnabled()) {
            logger.debug("Explicit transaction definition [" + transactionAttribute + "] found for test context " + testContext);
        }
        if (transactionAttribute.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
            return;
        }
        tm = getTransactionManager(testContext, transactionAttribute.getQualifier());
        Assert.state(tm != null, () -> String.format("Failed to retrieve PlatformTransactionManager for @Transactional test for test context %s.", testContext));
    }
    if (tm != null) {
        txContext = new TransactionContext(testContext, tm, transactionAttribute, isRollback(testContext));
        runBeforeTransactionMethods(testContext);
        txContext.startTransaction();
        TransactionContextHolder.setCurrentTransactionContext(txContext);
    }
}
Also used : TransactionAttribute(org.springframework.transaction.interceptor.TransactionAttribute) Method(java.lang.reflect.Method) PlatformTransactionManager(org.springframework.transaction.PlatformTransactionManager)

Example 4 with TransactionAttribute

use of org.springframework.transaction.interceptor.TransactionAttribute in project spring-framework by spring-projects.

the class AnnotationTransactionAttributeSourceTests method customClassAttributeDetected.

@Test
public void customClassAttributeDetected() throws Exception {
    Method method = TestBean5.class.getMethod("getAge");
    AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
    TransactionAttribute actual = atas.getTransactionAttribute(method, TestBean5.class);
    RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
    rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class));
    rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class));
    assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules());
}
Also used : TransactionAttribute(org.springframework.transaction.interceptor.TransactionAttribute) RuleBasedTransactionAttribute(org.springframework.transaction.interceptor.RuleBasedTransactionAttribute) RollbackRuleAttribute(org.springframework.transaction.interceptor.RollbackRuleAttribute) NoRollbackRuleAttribute(org.springframework.transaction.interceptor.NoRollbackRuleAttribute) RuleBasedTransactionAttribute(org.springframework.transaction.interceptor.RuleBasedTransactionAttribute) Method(java.lang.reflect.Method) NoRollbackRuleAttribute(org.springframework.transaction.interceptor.NoRollbackRuleAttribute) IOException(java.io.IOException) IOException(java.io.IOException) Test(org.junit.Test)

Example 5 with TransactionAttribute

use of org.springframework.transaction.interceptor.TransactionAttribute in project spring-framework by spring-projects.

the class AnnotationTransactionAttributeSourceTests method transactionAttributeDeclaredOnClassMethodWithJta.

@Test
public void transactionAttributeDeclaredOnClassMethodWithJta() throws Exception {
    Method getAgeMethod = ITestBean.class.getMethod("getAge");
    Method getNameMethod = ITestBean.class.getMethod("getName");
    AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
    TransactionAttribute getAgeAttr = atas.getTransactionAttribute(getAgeMethod, JtaAnnotatedBean1.class);
    assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, getAgeAttr.getPropagationBehavior());
    TransactionAttribute getNameAttr = atas.getTransactionAttribute(getNameMethod, JtaAnnotatedBean1.class);
    assertEquals(TransactionAttribute.PROPAGATION_SUPPORTS, getNameAttr.getPropagationBehavior());
}
Also used : TransactionAttribute(org.springframework.transaction.interceptor.TransactionAttribute) RuleBasedTransactionAttribute(org.springframework.transaction.interceptor.RuleBasedTransactionAttribute) Method(java.lang.reflect.Method) Test(org.junit.Test)

Aggregations

TransactionAttribute (org.springframework.transaction.interceptor.TransactionAttribute)23 Method (java.lang.reflect.Method)21 Test (org.junit.Test)21 RuleBasedTransactionAttribute (org.springframework.transaction.interceptor.RuleBasedTransactionAttribute)19 IOException (java.io.IOException)11 NoRollbackRuleAttribute (org.springframework.transaction.interceptor.NoRollbackRuleAttribute)11 RollbackRuleAttribute (org.springframework.transaction.interceptor.RollbackRuleAttribute)11 PlatformTransactionManager (org.springframework.transaction.PlatformTransactionManager)2 GroovyObject (groovy.lang.GroovyObject)1 DataSource (javax.sql.DataSource)1 ProxyFactory (org.springframework.aop.framework.ProxyFactory)1 ByteArrayResource (org.springframework.core.io.ByteArrayResource)1 ClassPathResource (org.springframework.core.io.ClassPathResource)1 Resource (org.springframework.core.io.Resource)1 ResourceDatabasePopulator (org.springframework.jdbc.datasource.init.ResourceDatabasePopulator)1 ITestBean (org.springframework.tests.sample.beans.ITestBean)1 AnnotationTransactionAttributeSource (org.springframework.transaction.annotation.AnnotationTransactionAttributeSource)1 DefaultTransactionAttribute (org.springframework.transaction.interceptor.DefaultTransactionAttribute)1 TransactionAttributeSource (org.springframework.transaction.interceptor.TransactionAttributeSource)1 TransactionInterceptor (org.springframework.transaction.interceptor.TransactionInterceptor)1