Reputation: 151
In the service layer, I have some method who have a transactional annotation.
@Transactional
public void process() throws ProcessPaymentException{
try{
.... do some operation
catch (ProcessPaymentException ppe) {
save db problem issue.
}
}
It seem like if there are a issue, there are roll back... and nothing is saved in the db...
ProcessPaymentException extend Exception
Is there a way to rollback the process in the try but do the save in the catch?
Edit
Nested transaction could be a solution if this link is ok https://www.credera.com/blog/technology-insights/java/common-oversights-utilizing-nested-transactions-spring/
Upvotes: 2
Views: 2476
Reputation: 40036
Existing answer of using ControllerAdvise
should help in normal setup that incoming requests are coming through Spring MVC (i.e. through a Controller
).
For cases that is not, or you do not want to tie your exception handling logic to Spring MVC, here are some alternatives I can think of
(Here I assume you want to rely on declarative transaction control instead of programmatically controlling transactions yourself)
Separate service/component to save error in different transaction.
In short, you can have a separate service, which create its own transaction by propagation REQUIRES_NEW
. e.g.
@Service
public class FooService
@Inject
private ErrorAuditService errorAuditService;
@Transactional
public void process() throws ProcessPaymentException{
try{
.... do some operation
catch (ProcessPaymentException ppe) {
errorAuditService.saveErrorAudit(ppe.getErrorText());
throw ppe; // I guess you want to re-throw the exception
}
}
}
@Service
public class ErrorAuditService
@Transactional(propagation=REQUIRES_NEW)
public void saveErrorAudit() {
// save to DB
}
}
One step further, if the error handling it the same for different services, you may create an advise, which will be called when service method throws exception. In that advise, you can save the error in db (using ErrorAuditService
), and rethrow the exception.
Upvotes: 1
Reputation: 142
Because processes of try-catch are wrapped by the same transaction. The transaction manager do rollback whenever an exception is thrown. So, not thing would be saved.
Is there a way to rollback the process in the try but do the save in the catch?
Yes. Create Exception Handler to save db problem issue after rollback. this is the idea
@ControllerAdvice
public class HandlerName {
@ExceptionHandler(ProcessPaymentException.class)
public void saveDbIssue(ProcessPaymentException ex) {
// save db problem issue.
}
But it only works if u want to save static data.
Upvotes: 0