Reputation: 4615
Consider I have a controller method get()
which calls a few service methods working with database.
Is it correct to make the entire controller method transactional or just every service method?
It seems to me that we must make get()
transactional because it performs associated operations.
Upvotes: 17
Views: 13270
Reputation: 11
You also need to consider that if you add it on the controller level then you may hold connection withing transaction for longer then needed. So it is good practice only wrap in transaction what is needed. I agree service level is more appropriate place.
So lets say you have few DB calls and API call withing controller method - best would be to wrap in the transaction only DB calls in case API will take long time to get response. For small volume application this may not make big difference but with high traffic you may run out of db connections.
@Transactional
public void initialPayment(PaymentRequest request) {
savePaymentRequest(request); // DB
callThePaymentProviderApi(request); // API - this should not be in transaction
updatePaymentState(request); // DB
saveHistoryForAuditing(request); // DB
}
Upvotes: 0
Reputation: 19789
I prefer to make only transactional the service methods that need to be transactional and control the transactionality in the service not in the controller. You can create a service method which englobes other service methods and with the spring transaction manage the transaction with propagation in @Transactional annotation.
@Transactional(propagation =...)
Edit
If I had 2 methods for example saveUser() and saveEmail() (because I store the emails in a database to send them later - like a queue) I would create in my service a method saveUserAndSendEmail(User user) which would be transactional. This method would call saveUser and saveEmail() each one in a @Repository component because they deal with the database. So I would put them in the @Repository components the methods to handle with the database and then I control the transactionality in the @Service component. Then the controller will only have to worry about providing the data and calling whenever they are needed. But I make a transaction because I don't want to commit changes in thedatabase until the whole method is executed successfully.
But this is the style I usually use, I'm not saying that this must be the way to go.
Upvotes: 10
Reputation: 403581
That's entirely up to you, and how you interpret your own business logic.
Spring doesn't really care where you put the transaction boundaries, and certainly doesn't limit you to putting them on your DAO classes.
So yes, adding @Transactional
to your controller methods is perfectly valid.
Upvotes: 11