8.2 使用保存点

X DevAPI 支持保存点,它允许你在事务中设置一个可回滚到的命名点。通过在事务中设置保存点,你可以稍后使用回滚功能撤消设置保存点之后发出的任何语句。如果不再需要保存点,则可以释放它们。本节介绍如何在 X DevAPI 中使用保存点。有关背景信息,请参见 SAVEPOINT

设置保存点

保存点由字符串名称标识。字符串可以包含标识符允许的任何字符。要创建保存点,请使用 session.setSavepoint() 操作,它映射到 SQL 语句 SAVEPOINT name;。如果你未指定 name,则会自动生成一个名称。例如,通过发出

session.setSavepoint()

将使用自动生成的名称创建一个事务保存点,并返回一个包含保存点名称的字符串。此名称可以与 session.rollbackTo()session.releaseSavepoint() 操作一起使用。可以在会话中多次调用 session.setSavepoint() 操作,每次都会生成唯一的保存点名称。

也可以通过传入字符串 name 来手动定义保存点的名称。例如,发出

session.setSavepoint('name')

将使用指定的 name 创建一个事务保存点,并由操作将其作为字符串返回。可以多次以这种方式调用 session.setSavepoint('name') 操作,如果 name 已用于保存点,则先前的保存点将被删除,并设置一个新的保存点。

回滚到保存点

当会话具有事务保存点时,可以使用 session.rollbackTo() 操作撤消任何后续事务,该操作映射到 ROLLBACK TO name 语句。例如,发出

session.rollbackTo('name')

将回滚到事务保存点 name。只要尚未释放给定的保存点,此操作就会成功。回滚到在其他保存点之前创建的保存点会导致后续保存点被释放或回滚。例如

session.startTransaction()
(some data modifications occur...)

session.setSavepoint('point1')     <---- succeeds
(some data modifications occur...)

session.setSavepoint('point2')     <---- succeeds
(some data modifications occur...)

session.rollbackTo('point1')       <---- succeeds
session.rollbackTo('point1')       <---- still succeeds, but position stays the same
session.rollbackTo('point2')       <---- generates an error because lines above already cleared point2
session.rollbackTo('point1')       <---- still succeeds

释放保存点

要取消保存点(例如,当不再需要它时),请使用 releaseSavepoint() 并传入要释放的保存点的名称。例如,发出

session.releaseSavepoint('name')

将释放保存点 name

保存点和隐式事务行为

保存点的确切行为由服务器定义,特别是如何配置自动提交。请参见 自动提交、提交和回滚

例如,请考虑以下没有显式 BEGINsession.startTransaction() 或类似调用的语句

session.setSavepoint('testsavepoint');
session.releaseSavepoint('testsavepoint');

如果在服务器上启用了自动提交模式,则这些语句会导致错误,因为名为 testsavepoint 的保存点不存在。这是因为对 session.setSavepoint() 的调用会创建一个事务,然后是保存点,并直接提交它。结果是,在发出对 releaseSavepoint() 的调用时,保存点不存在,而该调用在其自身的事务中。在这种情况下,要使保存点幸免,你需要先启动一个显式事务块。