Java JDBC上的保存点
我有一个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
保存点
;大概是这样的:
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”,可以吗?在这种情况下,我如何理解有多少tillSavepoint
工作正常
请告知如何理解,直到正确执行工作的保存点是什么?将此视为多个事务。因此,您可以使用多个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 {
}
}
}