Откат работает на транзакцию, но все равно завершается с ошибкой SQLNonTransientConnectionException - PullRequest
0 голосов
/ 04 марта 2020

Я работаю над приложением для продажи билетов в кино java. Существует сетка стульев, пользователь выбирает все стулья для бронирования, затем нажимает ОК, чтобы забронировать его (вставьте строки в базу данных mysql). Если из-за повторяющихся записей произойдет сбой в каком-либо из бронирований, все они будут отменены. Для этого прослушиванием кнопки «купить» я делаю:

    case "buy":         
        try {
        boolean success = true;         
            for(Booking b : bookingsToDo) {
                 if(DbConnect.getConnection().getAutoCommit())
                     DbConnect.getConnection().setAutoCommit(false);

                        success = controllerBooking.insertBooking(b);

                if(!success) {
                    JOptionPane.showMessageDialog(frameMain, "Error occurred, booking failed");

                    DbConnect.getConnection().rollback();                                               
                } 
            }

            if(success) {
                JOptionPane.showMessageDialog(frameMain, "Booking done");

                DbConnect.getConnection().commit();

            }

        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        break;

Это работает, потому что фактически все заказы меняются местами. Но в любом случае выдает: java. sql .SQLNonTransientConnectionException:

Невозможно вызвать откат, когда autocommit = true

, поэтому программа завершается с ошибкой. Как это возможно, что откат работает и в то же время выдает сообщение «Не удается откат»? И как это может быть, когда я делаю setAutoCommit (false) в каждом l oop?

1 Ответ

0 голосов
/ 05 марта 2020

DbConnect.getConnection() получает новое соединение каждый раз, когда оно вызывается.

Автокоммит устанавливается для каждого соединения отдельно. Поэтому вы откатываетесь по другому соединению. Контроллер Booking также нуждается в ссылке на соединение, чтобы использовать то же соединение.

Итак:

        con = DbConnect.getConnection(); 
        con.setAutoCommit(false);

        for(Booking b : bookingsToDo) {
            success = controllerBooking.insertBooking(con, b);

            if(!success) {
                JOptionPane.showMessageDialog(frameMain, "Error occurred, booking failed");

                con.rollback();                                               
                break;
            } 
        }
        con.commit();
...