数据库事务处理的核心概念:在标准的事务模型中,嵌套的内部事务的“提交”在外层事务失败时是无效的。所有操作,包括内部事务的操作,都将被回滚。
核心概念:真正的“嵌套事务” vs. “保存点”
首先要澄清一个关键点:大多数主流关系型数据库(如 Oracle, PostgreSQL, SQL Server)并不真正支持所谓的“嵌套事务”。它们使用的是 保存点 来模拟嵌套事务的行为。
-
真正的嵌套事务
-
这是一个理论模型,内部事务可以独立于外部事务提交或回滚。
-
如果内部事务提交,它的结果将立即持久化,即使外部事务后续回滚,内部事务的结果也会保留。
-
这种模型非常复杂,且在实际应用中较少见。一些对象数据库或特定的应用框架可能支持。
-
-
使用保存点模拟的嵌套事务(现实中的情况)
-
这是绝大多数数据库的实现方式。
-
当一个“内部事务”启动时(例如,在SQL Server中执行
BEGIN TRAN nested_tran
),数据库并不会创建一个新的事务,而是在当前事务中创建一个名为保存点的标记。 -
所谓的“内部事务提交”实际上只是释放或清除这个保存点,并没有真正地将数据持久化到磁盘。
-
真正的提交只有一个,那就是最外层的
COMMIT
操作。只有这个操作才能将数据永久写入数据库。 -
如果外层事务回滚(
ROLLBACK
),无论你是否创建了保存点或“提交”了内部事务,整个事务范围内的所有修改都将被撤销。
-
举个例子(以 SQL Server 为例)
结果会怎样?
所有在 OuterTran
事务中进行的操作,包括在 InnerTran1
和 InnerTran2
保存点之后所做的操作,全部都会被撤销。数据库将恢复到执行 BEGIN TRANSACTION OuterTran
之前的状态。
特殊情况:自治事务
有一种例外情况可以实现内部事务的真正提交,即自治事务。
-
自治事务 是一个独立的事务,它从调用它的父事务中独立出来。
-
即使在自治事务中提交,它的操作会立即持久化,不受父事务最终是提交还是回滚的影响。
-
Oracle 和 PostgreSQL(通过过程语言扩展)明确支持自治事务。
Oracle 自治事务示例:
结果会怎样?
尽管外层事务被回滚了,但自治事务 My_Autonomous_Proc
中的 INSERT
操作已经被提交,会永久保留在数据库中。
总结
场景 | 内部事务结果 | 常见数据库 |
---|---|---|
标准“嵌套事务”(实为保存点) | 全部回滚。内部事务的“提交”只是假象,最终依赖外层事务的提交。 | SQL Server, MySQL (InnoDB), PostgreSQL, Oracle |
真正的自治事务 | 提交有效。内部事务已独立提交,结果持久化,不受外层事务结果影响。 | Oracle, PostgreSQL (通过扩展) |
因此,在你的问题描述中,除非嵌套的内部事务被明确声明为自治事务,否则当最外层事务失败回滚时,所有内部操作都将被撤销,数据库保持一致状态。