I have a set of @Service
beans which inherit core functionality from an abstract class. I marked each of the concrete sub-class services with @Service
and @Transactional
. The abstract super class contains the public entry point method for each of these services. In other words, I have something similar to the following:
abstract class AbstractService {
public void process() {
// Do common initialisation code here
processSpecific();
// Do common completion code here
}
abstract protected void processSpecific();
}
@Service @Transactional
public class FirstSpecificService extends AbstractService {
protected void processSpecific() {
// Do specific processing code here
}
}
@Service @Transactional
public class SecondSpecificService extends AbstractService {
protected void processSpecific() {
// Do different specific processing code here
}
}
The specific code in each concrete sub-class service makes multiple calls to the DAO layer to make changes to the database, which have REQUIRED
as the transactional propagation type.
Now with the services defined as above, I discovered that there was no current transaction inside any of the code of these concrete sub-class services, and each call to the DAO layer was creating a new transaction, doing the changes, committing the transaction and returning.
However, if I annotate the abstract super-class with @Transactional
, then a transaction is created properly, and the sub-calls to the DAO layer all participate in the current transaction.
So my question is, what are the rules for inheriting the @Transactional
behaviour? Why does Spring not use the @Transactional
on the concrete sub-class services that it is actually instantiating? Does the @Transactional
need to be on the super-class in this case because that is where the public entry-point method is?
processSpecific()
that calls DAO , even then marking the subclass @Transactional didn't make process seem to have a Txn open – redzedi