【问题标题】:Why should i rollback after failed commit为什么我应该在提交失败后回滚
【发布时间】:2014-06-19 21:34:17
【问题描述】:

为什么在commit 失败后我应该rollback?万一,如果commit 失败,数据库无论如何都不会得到更改。那我为什么要打电话给rollback这种情况呢?

【问题讨论】:

  • 事务不会因为提交失败而结束。您想消除整个事务。
  • 回滚对于单个表或多个表的多个命令更有用。利用事务和回滚允许您使用一系列命令输入事务,然后如果任何一个单独的提交失败,您可以回滚事务中的所有命令。

标签: java database hibernate jpa transactions


【解决方案1】:

让我们以Oracle transaction management documentation 为例,它也适用于其他数据库引擎:

事务在提交或回滚时结束,无论是 显式地使用 COMMIT 或 ROLLBACK 语句或隐式地使用 COMMIT 或 ROLLBACK 语句 已发出 DDL 语句。

如果不指定 COMMIT/ROLLBACK,您可能会遇到以下情况:

  • 用户与 Oracle 数据库断开连接。当前事务已提交。

  • 用户进程异常终止。当前事务被回滚。

数据库事务管理基于事务日志:

  1. 从旧到新的状态转换记录在重做日志中。
  2. 从新到旧的状态转换记录在撤消日志中。

由于事务隔离要求,数据会根据实际表结构进行更改,并且锁定机制可以防止其他事务看到未提交的更改。实际数据发生了变化,因为当前事务需要在事务生命周期内读取自己的写入。

所以实际数据发生了变化,但由于我们同时拥有重做和撤消日志,我们可以轻松地提交/回滚甚至回滚针对给定数据源成功提交的不确定的分布式事务,同时全局事务失败,因为其他登记的数据源已回滚。

回滚包括撤消当前未提交事务记录的所有数据更改,因此如果当前事务失败,您应该ROOBACK。

【讨论】:

    【解决方案2】:

    我认为 COMMIT 失败的原因只有两个:

    1. dbms 不可用或损坏。
    2. 延迟约束生效。

    据我所知,T-SQL 不支持延迟约束。即使它这样做了,它也应该在失败时执行一个隐式的 ROLLBACK。

    关于 dbms 不可用或损坏:好吧,如果 COMMIT 不起作用,为什么要 ROLLBACK?

    结论:我认为没有理由在 COMMIT 失败时执行 ROLLBACK。

    【讨论】:

    • 至少应该检查一下“失败”在您的用例中的含义。例如,SQLite 可以返回 SQLITE_BUSY 以响应提交。如果将此视为提交失败,则应回滚事务。如果不回滚事务,受影响的数据库连接的下一个 BEGIN 将失败,因为前一个事务仍然处于活动状态。
    猜你喜欢
    • 2020-01-31
    • 2012-03-04
    • 2011-01-23
    • 2021-09-15
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 2012-06-27
    • 1970-01-01
    相关资源
    最近更新 更多