Java JDBC上的保存点

Java JDBC上的保存点,java,oracle,jdbc,savepoints,Java,Oracle,Jdbc,Savepoints,我有一个JDBC代码,其中存在多个保存点;大概是这样的: 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.setS

我有一个JDBC代码,其中存在多个
保存点
;大概是这样的:

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块中,我捕获异常并检查
保存点是否为
null
;如果是,则回滚整个连接,否则回滚到
保存点。但我无法理解在回滚哪个
保存点之前

如果我将所有保存点名称都更改为“S1”,可以吗?在这种情况下,我如何理解有多少till
Savepoint
工作正常


请告知如何理解,直到正确执行工作的保存点是什么?

将此视为多个事务。因此,您可以使用多个try/catch块来处理此问题。您似乎还覆盖了保存点对象,因此回滚是不可行的

更多信息。 JDBC还支持设置保存点,然后回滚到指定的保存点。可以使用以下方法定义保存点

SavePoint savePoint1 = connection.setSavePoint();
使用带参数的回滚调用将事务回滚到已定义的存储点

connection.rollback(savePoint1);
参考资料。

在这种情况下,我发现棘手的部分是确保只有在所有插入成功时才提交事务,但如果任何插入失败,则回滚所有更新。我使用了一个保存点堆栈来处理这种情况。高度简化的代码如下所示:

连接包装器类:

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 {

        }
    }
}