SAVEPOINT是创建事务的一种方法,类似于BEGIN和COMMIT,区别在于SAVEPOINT和RELEASE命令有名称,并且可以嵌套。
SAVEPOINT命令使用名称启动一个新的事务。事务名称不必唯一。SAVEPOINT可以在BEGIN...COMMIT内部或外部启动。当SAVEPOINT是最外层的保存点且不在BEGIN...COMMIT内部时,其行为与BEGIN DEFERRED TRANSACTION相同。
ROLLBACK TO命令将数据库状态恢复到与相应SAVEPOINT启动后的状态一致。请注意,与普通ROLLBACK命令(不带TO关键字)不同,ROLLBACK TO命令不会取消事务。ROLLBACK TO命令不会取消事务,而是从头开始重新启动事务。但是,所有中间SAVEPOINT都会被取消。
RELEASE命令类似于SAVEPOINT的COMMIT。RELEASE命令会使从最近的具有相同名称的保存点开始的所有保存点从事务栈中删除。内部事务的RELEASE不会导致任何更改写入数据库文件;它只是从事务栈中删除保存点,这样就不能再ROLLBACK TO这些保存点了。如果RELEASE命令释放了最外层的保存点,使事务栈变为空,则RELEASE与COMMIT相同。即使事务最初是通过SAVEPOINT命令而不是BEGIN命令启动的,也可以使用COMMIT命令释放所有保存点并提交事务。
如果RELEASE命令中的savepoint-name与事务栈中当前的任何保存点都不匹配,则不会释放任何保存点,数据库保持不变,并且RELEASE命令返回错误。
请注意,内部事务可能会提交(使用RELEASE命令),但随后可能会被外部事务中的ROLLBACK撤销。断电、程序崩溃或操作系统崩溃会导致最外层事务回滚,撤销该最外层事务中发生的更改,即使是那些已经被RELEASE命令“提交”的更改。在最外层事务提交之前,内容不会真正写入磁盘。
有几种方法可以理解RELEASE命令。
有些人认为RELEASE等同于SAVEPOINT的COMMIT。只要记住内部事务提交的更改可能会被外部事务中的回滚撤销,这是一种可以接受的观点。
RELEASE的另一种观点是它将命名的事务合并到其父事务中,这样命名事务及其父事务就成为同一个事务。在RELEASE之后,命名事务及其父事务将一起提交或回滚,无论它们最终会发生什么。
还可以将保存点视为事务时间轴上的“标记”。在这种情况下,SAVEPOINT命令创建一个新的标记,ROLLBACK TO命令将时间轴倒带到命名标记之后的点,RELEASE命令擦除时间轴上的标记,但实际上不会对数据库进行任何更改。
最后开始的事务将是第一个提交或回滚的事务。
只有当事务栈为空时,BEGIN命令才有效,换句话说,没有待处理的事务。如果在调用BEGIN命令时事务栈不为空,则该命令会失败并返回错误。
COMMIT命令会提交所有未决事务并将事务栈清空。
RELEASE命令从事务栈中最新的添加开始,向后释放保存点,直到它释放一个具有匹配savepoint-name的保存点。之前的保存点(即使是具有匹配savepoint-name的保存点)保持不变。如果RELEASE命令导致事务栈变为空(如果RELEASE命令从栈中释放最外层事务),则该事务会提交。
不带TO子句的ROLLBACK命令会回滚所有事务并将事务栈清空。
带TO子句的ROLLBACK命令会向后回滚事务,回到具有匹配名称的最近的SAVEPOINT。具有匹配名称的SAVEPOINT会保留在事务栈中,但该SAVEPOINT创建后发生的数据库更改会回滚。如果ROLLBACK TO命令中的savepoint-name与栈中任何SAVEPOINT都不匹配,则ROLLBACK命令会失败并返回错误,数据库状态保持不变。
本页面上次修改于2022-01-08 05:02:57 UTC