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),