Home > front end >  Is guaranteed in Spring that int values of TransactionDefinition and Propagation are always same?
Is guaranteed in Spring that int values of TransactionDefinition and Propagation are always same?

Time:07-22

I would like to work with DefaultTransactionDefinition and create it using a custom method.

public DefaultTransactionDefinition definition(int timeout, int propagationBehavior) {
    final TransactionTemplate transactionTemplate = new TransactionTemplate(...);
    transactionTemplate.setPropagationBehavior(propagationBehavior);
    transactionTemplate.setTimeout(timeoutSeconds);
    ...
    return transactionTemplate;
}

The API suggests using TransactionDefinition interface to represent the propagation behavior:

Default implementation of the TransactionDefinition interface, offering bean-style configuration and sensible default values (PROPAGATION_REQUIRED, ISOLATION_DEFAULT, TIMEOUT_DEFAULT, readOnly=false).

public interface TransactionDefinition {

    int PROPAGATION_REQUIRED = 0;
    int PROPAGATION_SUPPORTS = 1;
    int PROPAGATION_MANDATORY = 2;
    int PROPAGATION_REQUIRES_NEW = 3;
    ...

With all respect to the creators, one has to be really wasted to define "sensible" values as int in an interface. The code becomes error-prone:

// BOOM: both compile but the latter is completely wrong
DefaultTransactionDefinition d1 = definition(3000, TransactionDefinition.PROPAGATION_REQUIRES_NEW);
DefaultTransactionDefinition d2 = definition(TransactionDefinition.PROPAGATION_REQUIRES_NEW, 3000);

Keep reading: I would like to overcome this issue using the Propagation instead which is a proper enum:

public enum Propagation {
    REQUIRED(0),
    SUPPORTS(1),
    MANDATORY(2),
    REQUIRES_NEW(3),
    ...
public DefaultTransactionDefinition definition(int timeout, Propagation propagation) {
    final TransactionTemplate transactionTemplate = new TransactionTemplate(...);
    transactionTemplate.setPropagationBehavior(propagation.value());
    transactionTemplate.setTimeout(timeoutSeconds);
    ...
    return transactionTemplate;
}
DefaultTransactionDefinition d1 = definition(3000, Propagation.REQUIRES_NEW);
DefaultTransactionDefinition d2 = definition(Propagation.REQUIRES_NEW, 3000); // correctly doesn't compile

Although, the Propagation class is in the org.springframework.transaction.annotation package suggests this shall be used only for the @Transactional annotation, I can close my eyes and pretend it is ok.

Now the question:

As long as there is no reference between TransactionDefinition and Propagation, how can I be assured that the integer 3 always represents the propagation REQUIRE_NEW etc? These two classes are completely disconnected and duplicate code.

I have trust issues: is there any reference to the documentation explaining the usage of both classes and whether these "constants" respect each other?

CodePudding user response:

The documentation of Propagation says:

Enumeration that represents transaction propagation behaviors for use with the Transactional annotation, corresponding to the TransactionDefinition interface.

So, yes, you can expect this to work as it is documented to correspond.

In addition, the actual source code of Propagation uses the constants of TransactionDefinition:

public enum Propagation {

    /**
     * Support a current transaction, create a new one if none exists.
     * Analogous to EJB transaction attribute of the same name.
     * <p>This is the default setting of a transaction annotation.
     */
    REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

  • Related