Andrey Minogin
Andrey Minogin

Reputation: 4615

Transactional: controller vs service

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

Answers (3)

domminus
domminus

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

Javi
Javi

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

skaffman
skaffman

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

Related Questions