Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当我们调用rollback时,有多少个提交被回滚?_Java_Sql_Oracle_Jdbc - Fatal编程技术网

Java 当我们调用rollback时,有多少个提交被回滚?

Java 当我们调用rollback时,有多少个提交被回滚?,java,sql,oracle,jdbc,Java,Sql,Oracle,Jdbc,当我们有两个或多个提交时,回滚的行为是什么 Connection conn= getConnection(); try{ doSomeInsertOrUpdateStep1(conn); //some sql update/insert using connection conn.commit(); //step 1 doSomeInsertOrUpdateStep2(conn); //some sql update/insert using connection conn.commit(

当我们有两个或多个提交时,回滚的行为是什么

Connection conn= getConnection();

try{

doSomeInsertOrUpdateStep1(conn); //some sql update/insert using connection
conn.commit(); //step 1

doSomeInsertOrUpdateStep2(conn); //some sql update/insert using connection
conn.commit(); //step 2

//ERROR IS THROWN HERE AFTER SECOND COMMIT
} catch(Exception e){

   conn.rollback(); //what will be rolledback exactly step 1 or step2 or both?

}

如果在第二次提交后抛出错误,我不知道在这种情况下应该回滚什么。

这取决于异常发生的时间

例如,如果在第一次提交之后和第二次提交之前抛出异常,则回滚将撤消由
doSomeInsertOrUpdateStep2(conn)执行的任何DB更新

另一方面,如果在第一次提交之前抛出异常,则catch块的回滚将撤消由
doSomeInsertOrUpdateStep1(conn)执行的任何DB更新(在本例中,
doSomeInsertOrUpdateStep2(conn);
根本不会执行)

任何已提交的更新都不会回滚。

来自:

使用COMMIT语句结束当前事务,并永久更改事务中执行的所有更改

[……]

在提交事务之前:[……]可以使用ROLLBACK语句回滚(撤消)事务期间所做的任何更改

因此,基本上您的代码的工作原理如下:

  • 运行第一个查询:如果成功,则提交并继续;else回滚(还原在执行第一条语句之前所做的任何未提交的更改)和停止(不运行下一条语句)
  • 运行第二条语句:如果成功,则提交,否则回滚。请注意,由于COMMIT是在执行语句之前执行的,因此无论如何都不会回滚任何内容
我认为这个逻辑可能会被优化。根据我的理解,您可能希望在单个事务中运行这两个查询,这意味着:要么两个查询都成功,您希望提交它们,要么如果任何查询失败,您希望回滚所有查询


要实现该行为,您需要删除第一次提交(在第一次查询成功执行之后)。

rollback
应该在
COMMIT
之前发出。否则没有意义。当您提交某件事情时,回滚不会影响它。回滚用于撤消尚未提交的工作。所以这实际上取决于抛出异常的时间。在第二次提交之后,我更新了错误的位置。@BarbarosÖzhan提交之前应该如何使用回滚?如果没有提交任何内容,那么它将回滚什么?请参考上面的@Todd注释,这非常有用,并且解释得很好。@AhmedAbouhegaza如果在第二次提交之后抛出异常,则不会回滚任何内容(假设抛出异常的代码没有进行任何数据库更新)实际上,场景是在两次提交中都对DB进行了一些更改,并且在第二次提交时或之后抛出了一个错误,回滚将回滚什么?提交1个更改或提交2个更改,或两者都提交?Thanks@AhmedAbouhegazacommit1的更改不会回滚,因为您说commit没有失败。如果在第二次提交期间引发了异常,则在第一次提交之后所做的所有更改都将回滚。如果在第二次提交后抛出,则在第二次提交后所做的任何更改都将回滚。您是说失败的提交不会自动回滚吗?如果是这样,那么回滚有什么用呢?谢谢你的帮助@失败的提交可能会自动回滚。我不确定。无论哪种方式,显式回滚都会取消所有尚未取消的未提交更改。谢谢,只是为了澄清,案例1:如果提交成功,然后我们执行回滚,那么回滚将毫无意义,因为提交已完成。案例2,如果在提交期间发生异常,我们捕获并回滚,那么回滚将撤消此提交所发生的更改。这对我来说有点困惑,所以任何帮助都将不胜感激。谢谢@艾哈迈达布哈加。。。提交不会产生错误,少数情况除外;插入/更新通常更容易产生错误,我想这就是您的代码打算处理的。但是,为了回答您的问题,如果提交本身失败,则意味着无法保存数据;它将被捕获并发生回滚,这将撤消所有未提交的更改,直到该点。