Transactions are technically processed by the data access layer. However, the transaction control has to be performed in upper layers. To avoid dependencies on persistence layer and technical code in upper layers, we use AOP to add transaction control via annotations as aspect.
We recommend using the @Transactional
annotation (the JEE standard javax.transaction.Transactional
rather than org.springframework.transaction.annotation.Transactional
). We use this annotation in the logic layer to annotate business methods that participate in transactions (what typically applies to most up to all business components):
@Transactional
public MyDataTo getData(MyCriteriaTo criteria) {
...
}
In case a service operation should invoke multiple use-cases, you would end up with multiple transactions what is undesired (what if the first TX succeeds and then the second TX fails?). Therefore you would then also annotate the service operation. This is not proposed as a pattern in any case as in some rare cases you need to handle constraint-violations from the database to create a specific business exception (with specified message). In such case you have to surround the transaction with a try {} catch
statement what is not working if that method itself is @Transactional
.
Transaction control for batches is a lot more complicated and is described in the batch layer.