13.6.1Using the TransactionTemplate

TheTransactionTemplateadopts the same approach as other Spring_templates_such as theJdbcTemplate. It uses a callback approach, to free application code from having to do the boilerplate acquisition and release of transactional resources, and results in code that is intention driven, in that the code that is written focuses solely on what the developer wants to do.

As you will see in the examples that follow, using theTransactionTemplateabsolutely couples you to Spring’s transaction infrastructure and APIs. Whether or not programmatic transaction management is suitable for your development needs is a decision that you will have to make yourself.

Application code that must execute in a transactional context, and that will use theTransactionTemplateexplicitly, looks like the following. You, as an application developer, write aTransactionCallbackimplementation (typically expressed as an anonymous inner class) that contains the code that you need to execute in the context of a transaction. You then pass an instance of your customTransactionCallbackto theexecute(..)method exposed on theTransactionTemplate.

public class SimpleService implements Service {

    // single TransactionTemplate shared amongst all methods in this instance
    private final TransactionTemplate transactionTemplate;

    // use constructor-injection to supply the PlatformTransactionManager
    public SimpleService(PlatformTransactionManager transactionManager) {
        Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
        this.transactionTemplate = new TransactionTemplate(transactionManager);
    }

    public Object someServiceMethod() {
        return transactionTemplate.execute(new TransactionCallback() {
            // the code in this method executes in a transactional context
            public Object doInTransaction(TransactionStatus status) {
                updateOperation1();
                return resultOfUpdateOperation2();
            }
        });
    }
}

If there is no return value, use the convenientTransactionCallbackWithoutResultclass with an anonymous class as follows:

transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    protected void doInTransactionWithoutResult(TransactionStatus status) {
        updateOperation1();
        updateOperation2();
    }
});

Code within the callback can roll the transaction back by calling thesetRollbackOnly()method on the suppliedTransactionStatusobject:

transactionTemplate.execute(new TransactionCallbackWithoutResult() {

    protected void doInTransactionWithoutResult(TransactionStatus status) {
        try {
            updateOperation1();
            updateOperation2();
        } catch (SomeBusinessExeption ex) {
            status.setRollbackOnly();
        }
    }
});

Specifying transaction settings

You can specify transaction settings such as the propagation mode, the isolation level, the timeout, and so forth on theTransactionTemplateeither programmatically or in configuration.TransactionTemplateinstances by default have thedefault transactional settings. The following example shows the programmatic customization of the transactional settings for a specificTransactionTemplate:

public class SimpleService implements Service {

    private final TransactionTemplate transactionTemplate;

    public SimpleService(PlatformTransactionManager transactionManager) {
        Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
        this.transactionTemplate = new TransactionTemplate(transactionManager);

        // the transaction settings can be set here explicitly if so desired
        this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
        this.transactionTemplate.setTimeout(30); // 30 seconds
        // and so forth...
    }
}

The following example defines aTransactionTemplatewith some custom transactional settings, using Spring XML configuration. ThesharedTransactionTemplatecan then be injected into as many services as are required.

<bean id="sharedTransactionTemplate"
        class="org.springframework.transaction.support.TransactionTemplate">
    <property name="isolationLevelName" value="ISOLATION_READ_UNCOMMITTED"/>
    <property name="timeout" value="30"/>
</bean>"

Finally, instances of theTransactionTemplateclass are threadsafe, in that instances do not maintain any conversational state.TransactionTemplateinstances_do_however maintain configuration state, so while a number of classes may share a single instance of aTransactionTemplate, if a class needs to use aTransactionTemplatewith different settings (for example, a different isolation level), then you need to create two distinctTransactionTemplateinstances.

results matching ""

    No results matching ""