Should you place the @Transactional
in the DAO
classes and/or their methods or is it better to annotate the Service classes which are calling using the DAO objects? Or does it make sense to annotate both "layers"?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
For Transaction in database level
mostly I used
@Transactional
in DAO's just on method level, so configuration can be specifically for a method / using default (required)DAO's method that get data fetch (select .. ) - don't need
@Transactional
this can lead to some overhead because of transaction interceptor / and AOP proxy that need to be executed as well.DAO's methods that do insert / update will get
@Transactional
very good blog on transctional
For application level -
I am using transactional for business logic I would like to be able rolback in case of unexpected error
The normal case would be to annotate on a service layer level, but this really depends on your requirements.
Annotating on a service layer will result in longer transactions than annotating on DAO level. Depending on the transaction isolation level that can youse problems, as concurrent transactions wont see each other's changes in eg. REPEATABLE READ.
Annotating on the DAOs will keep the transactions as short as possible, with the drawback that the functionality your service layer is exposing wont be done in a single (rollbackable) transaction.
It does not make sense to annotate both layers if the propagation mode is set to default.
Usually, one should put a transaction at the service layer.
But as stated before, the atomicity of an operation is what tells us where an annotation is necessary. Thus, if you use frameworks like Hibernate, where a single "save/update/delete/...modification" operation on an object has the potential to modify several rows in several tables (because of the cascade through the object graph), of course there should also be transaction management on this specific DAO method.
I place the
@Transactional
on the@Service
layer and setrollbackFor
any exception andreadOnly
to optimize the transaction further.By default
@Transactional
will only look forRuntimeException
(Unchecked Exceptions), by setting rollback toException.class
(Checked Exceptions) it will rollback for any exception.See Checked vs. Unchecked Exceptions.
@Transactional
Annotations should be placed around all operations that are inseparable. Using@Transactional
transaction propagation are handled automatically.In this case if another method is called by current method,then that method will have the option of joining the ongoing transaction.So lets take example:
We have 2 model's i.e.
Country
andCity
. Relational Mapping ofCountry
andCity
model is like oneCountry
can have multiple Cities so mapping is like,Here Country mapped to multiple cities with fetching them
Lazily
. So here comes role of@Transactinal
when we retrieve Country object from database then we will get all the data of Country object but will not get Set of cities because we are fetching citiesLAZILY
.When we want to access Set of Cities from country object then we will get null values in that Set because object of Set created only this Set is not initialize with there data to get values of Set we use
@Transactional
i.e.,So basically
@Transactional
is Service can make multiple call in single transaction without closing connection with end point.I think transactions belong on the Service layer. It's the one that knows about units of work and use cases. It's the right answer if you have several DAOs injected into a Service that need to work together in a single transaction.