0
votes

I have a Spring @Service bean in which some data saving in a MySQL occurs. It's saving LocalDateTime objects, for booking rooms in future dates.

The problem is: when booking multiple rooms at once and one of them is not available (i.e. already booked), Spring should rollback all the rooms that were booked already, but isn't doing it. Everything but the error one is commited to the database.

Code inside my @Service, the one that should rollback after an exception is thrown.

@Transactional(rollbackFor = { RecurrentMeetingBookingException.class})
public void bookRecurringMeeting(RecurrentMeeting meeting) throws RecurrentMeetingBookingException {
    LocalDateTime start = meeting.getMeetingEntity().getStartDate();
    LocalDateTime end = meeting.getMeetingEntity().getEndDate();

    while (start.isBefore(meeting.getRecurrenceEndTime())) {
        MeetingEntity recurrent = copyOfRecurrent(meeting, start, end);

        try {
            bookRoomForDate(recurrent);
        } catch (MeetingException e) {
            throw new RecurrentMeetingBookingException(e.getMessage());
        }

        start = start.plus(1, meeting.getRecurrenceType().getUnitOfTime());
        end = end.plus(1, meeting.getRecurrenceType().getUnitOfTime());
    }
}

I tried throwing a RuntimeException too, but it also didn't work.

When returning a ResponseEntity from my Controller, the exception is indeed thrown, as I return Room is not available as an exception, returning it's message.


What is the problem with my @Transactional? Shouldn't Spring/Hibernate rollback everything when an exception is thrown? What can I do to solve this issue, and correctly rollback the @Transactional?

1
Assuming that the bookRecurringMeeting method is declared in the @Service class named BookService, The @Controller is using how a dependency the BookService class?. If your @RequestMapping is not calling directly the bookRecurringMeeting method, then the @Transactional attribute is not working how is expected. Consider post your @Controller code. I had this behaviour too. - Manuel Jordan
My problem was another one, I posted it below. Spent way too many hours finding a solution to not post it back to the community. I'll add the extra codes when I have a chance, but the @RestController was calling bookRecurringMeeting directly. - MoisesCol
Do you have either <tx:annotation-driven> or @EnableTransactionManagement declared? See stackoverflow.com/questions/26203446/… - Manuel Jordan
Yes, @ManuelJordan. The problem solution is described in my answer. - MoisesCol

1 Answers

0
votes

When facing this problem, a member from the spring forums came with a solution, back in 2011.


Make sure you're using transactional tables, for example INNODB

You might be using a non-transactional table, for instance MyISAM, and @Transactional won't work as expected.

This isn't exactly a Spring/Hibernate problem, but your database's.