Точка сохранения на JDBC

1

У меня есть JDBC-код, в котором присутствует несколько Savepoints; что-то вроде этого:

1st insert statement
2nd insert statement
savepoint = conn.setSavepoint("S1");
1st insert statement
2nd update statement
savepoint = conn.setSavepoint("S2");
1st delete statement
2nd delete statement
savepoint = conn.setSavepoint("S3");
1st insert statement
2nd delete statement
savepoint = conn.setSavepoint("S4");

Теперь в блоке catch я улавливаю исключение и проверяю, является ли Savepoint null или нет; если да, то откат всего отката от другого соединения еще до Savepoint. Но я не могу понять, до чего Savepoint.

Будет ли хорошо, если я изменю все имена точек сохранения на "S1"? В таком случае, как я пойму, сколько еще до Savepoint работало правильно?

Пожалуйста, посоветуйте, как понять, до каких результатов Savepoint работа была выполнена правильно?

Теги:
jdbc
savepoints

2 ответа

2
Лучший ответ

Будет рассматривать это как несколько транзакций. Следовательно, вы можете справиться с этим несколькими блоками try/catch. Вы также, кажется, переписываете объекты точки сохранения, поэтому было бы невозможно откат.

Больше информации. JDBC также поддерживает установку точек сохранения, а затем откат в указанную точку сохранения. Для определения точек сохранения можно использовать следующий метод.

SavePoint savePoint1 = connection.setSavePoint();

Откат транзакции в уже определенную точку сохранения с помощью обратного вызова с аргументом.

connection.rollback(savePoint1);

Справка. http://www.sourcetricks.com/2014/08/jdbc-handling-transactions.html

3

В таких случаях я обнаружил, что сложная часть заключается в том, чтобы убедиться, что вы совершили транзакцию, только если все вставки успешно, но откатите все обновления, если какая-либо вставка завершилась с ошибкой. Я использовал стек точки сохранения для обработки таких ситуаций. Очень упрощенный код выглядит следующим образом:

Класс оболочки подключения:

public class MyConnection {
    Connection conn;
    static DataSource ds;
    Stack<Savepoint> savePoints = null;

    static {
        //... stuff to initialize datasource.
    }

    public MyConnection() {
        conn = ds.getConnection();
    }

    public void beginTransaction() {
        if (savePoints == null) {
            savePoints = new Stack<Savepoint>();
            conn.setAutoCommit(false);
            conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
        } else {
            savePoints.push(conn.setSavepoint());
        }
    }

    public void commit() throws SQLException {
        if (savePoints == null || savePoints.empty()) {
            conn.commit();
        } else {
            Savepoint sp = savePoints.pop();
            conn.releaseSavepoint(sp);
        }
    }

    public void rollback() throws SQLException {
        if (savePoints == null || savePoints.empty()) {
            conn.rollback();
        } else {
            Savepoint sp = savePoints.pop();
            conn.rollback(sp);
        }
    }

    public void releaseConnection() {
        conn.close();
    }
}

Затем вы можете использовать различные методы, которые могут быть вызваны независимо или в сочетании. В приведенном ниже примере метод А может быть вызван сам по себе или в результате вызова метода Б.

public class AccessDb {

    public void methodA(MyConnection myConn) throws Exception {
        myConn.beginTransaction();
        try {
            // update table A
            // update table B
            myConn.commit();
        } catch (Exception e) {
            myConn.rollback();
            throw e;
        } finally {

        }
    }

    public void methodB(MyConnection myConn) throws Exception {
        myConn.beginTransaction();
        try {
            methodA(myConn);
            // update table C
            myConn.commit();
        } catch (Exception e) {
            myConn.rollback();
            throw e;
        } finally {

        }
    }
}

Таким образом, если что-то пойдет не так, оно полностью откатится (в результате обработки исключений), но только совершит транзакцию, а не совершит частично завершенную транзакцию.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню