返回首页

gbase数据、南大通用产品文档:GBase8sSAVEPOINT 语句

更新日期:2024年09月11日

使用 SAVEPOINT 语句来声明在当前的 SQL 事务之内新的保存点的名称,并设
置在该事务之内 SQL 语句的词典顺序之内的新保存点的位置。SAVEPOINT 语
句符合 SQL 的 ANSI/ISO 标准。
语法

元素
描述
限制
语法
savepoint 在此为新的保存
点声明的名称
不可为在相同的保存点级别中现
有的唯一保存点的名称
标识符
用法
您可在 SQL 事务中使用 SAVEPOINT 语句以 DB-Access 和 SPL、C 和 Java™
例程来支持错误处理。您可定义保存点来将单个复杂的事务分隔成它的组件 SQL
语句的较小的逻辑子集。在那个事务之内,可更有效地回滚跟在每一保存点之后
的语句的子集,比起如果您在多个事务中已使用了多个 COMMIT WORK 和
ROLLBACK WORK 语句的话。
SAVEPOINT 语句在当前的事务之内按照语句的词典顺序在当前的位置设置指定
的保存点。在 SAVEPOINT 语句执行成功之后,引用此保存点的后续的
ROLLBACK TO SAVEPOINT 语句可取消对数据库任何未提交的更改,这些更改
是跟在新的保存点之后但在 ROLLBACK TO SAVEPOINT 语句之前的。
如果在同一事务内的现有的保存点与 SAVEPOINT 语句指定的名称相同,则销毁现
有的保存点,除非下列条件之一为真:

在不同的保存点级别设置了现有的保存点。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 847

以 UNIQUE 关键字选项声明了现有的保存点名称。在此情况下
SAVEPOINT 语句失败并报错,除非在不同的保存点级别设置了现有的
UNIQUE 保存点。
销毁一保存点来为另一保存点重用它的名称,与释放该保存点不同。重用保存点
名称仅销毁一个保存点。以 RELEASE SAVEPOINT 语句释放保存点会释放指定
的保存点以及后续已设置了的所有保存点。
UNIQUE 选项
此可选的关键字指定应用程序不要打算在另一 SAVEPOINT 语句中重用此保存点
的名称,在此保存点在当前的保存点级别之内是活动的时候。
如果保存点已存在,是在当前的保存点界别之内以相同的名称和以 UNIQUE 关
键字设置了的,则 SAVEPOINT 语句失败并报错,且不销毁现有的保存点。
保存点级别
GBase 8s 支持构造嵌套的保存点级别。单个 SQL 事务可有多个保存点级别。在
执行 SPL 例程或外部 UDR 期间,自动地创建新的保存点级别。递归地调用相
同的 SPL 例程或 UDR 还增长当前事务的保存点级别。
当在其被创建的 UDR 中完成执行时,保存点级别终止。当保存点级别终止时,
自动地释放在它之内的所有保存点。父保存点级别继承任何 DDL 或 DML 修改
(即,到在其内创建了刚刚终止的那个保存点级别),并受任何针对该父保存点
级别发出的保存点相关的语句支配。
下列规则适用于保存点级别之内的活动:

仅可在保存点被创建的那个保存点级别之内引用保存点。您不可释放、销
毁或回滚到在当前保存点级别之外创建的保存点。
保存点名称的唯一性仅在当前的保存点级别之内是强制的。在其他保存点级别中
为活动的保存点的名称可在当前的保存点级别中重用,而不影响其他保存点级别
中的那些保存点。
在分布式 SQL 事务中的保存点
如果所有参与的数据库支持事务日志记录,则保存点在支持事务的单个 GBase 8s
实例的跨数据库分布式 SQL 事务中是有效的。在跨数据库 SQL 事务中还支持

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 848
保存点,包括在高可用性集群中的操作,如果所有参与的 GBase 8s 实例支持保
存点,且在该事务中访问的所有数据库都使用日志记录的话。
然而,如果在跨数据库事务中的任何参与的数据库服务器不支持保存点,且在可
支持保存点的协调者与不支持保存点的从属服务器之间建立了连接,则在分布式
会话之内的任何 ROLLBACK TO SAVEPOINT 语句都失败并报错。
保存点的保持
保存点是 SQL 事务之内,而不是数据库对象之内的位置标记。在同一事务之内,
任何下列事件之一都销毁现有的保存点 S:

执行 COMMIT WORK 或 ROLLBACK WORK(无 TO SAVEPOINT 子
句)语句。

执行在同一保存点级别中指定 S 的 RELEASE SAVEPOINT 语句。

执行 ROLLBACK TO SAVEPOINT 或 RELEASE SAVEPOINT 语句,指
定早于在同一保存点级别中的 S 建立了的保存点。

在同一保存级别中 SAVEPOINT 语句指定相同的名称作为 S,且 S 不
是以 UNIQUE 关键字创建的。
对保存点的限制
在下列上下文中不支持保存点和保存点级别:

在不支持事务日志记录的数据库中

在触发器活动中

在 XA 全局事务中

在启用 AUTOCOMMIT 连接属性的应用程序或 UDR 中。
此外,在 DML 语句之内调用的 UDR 中,SAVEPOINT 语句(如 RELEASE
SAVEPOINT 和 ROLLBACK WORK TO SAVEPOINT 语句)是无效的,如下例
所示:
SELECT first_1 foo() FROM systables;
在此,foo( ) 例程不可设置保存点。
相关的语句
相关的语句:COMMIT WORK 语句、RELEASE SAVEPOINT 语句 和
ROLLBACK WORK 语句

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 849

以下主题概述了确定数据库一致性并更正相关情况(如果需要)的过程中的步骤。
以下主题中描述了其中每个步骤。

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 511 -
确定事务是否不一致地实现
首要任务是确定事务是否由于独立操作而不一致地实现。
全局事务过早结束
如果运行了 onmode -z 命令来结束协调者上的全局事务,那么事务可能会不一致地实现。
(有关该情况会如何发生的说明,请参阅导致错误条件的独立操作。)您可以通过首先检
查数据库服务器消息日志来检查协调者是否有不一致的事务。查找以下错误消息:
-716 Possible inconsistent transaction.
Unknown servers are server-name-list.
该消息列出所有充当参与者的数据库服务器。 检查每个参与者的逻辑日志。如果至少一
个参与者执行了落实且一个参与者执行了回滚,那么事务不一致地实现。
启发式结束事务
如果运行了 onmode -Z address 命令来结束某个参与者执行的工作片段,并且协调者决定
落实事务,那么事务将不一致地实现。(有关该应用场合的描述,请参阅启发式结束事务
场景。)检查每个参与者的逻辑日志。如果至少一个参与者执行了落实且一个参与者执行
了回滚,那么事务不一致地实现。
启发式回滚
您可以用以下方法来确定启发式决策所影响的特定数据库服务器参与者,从而回滚事务:
检查应用程序中 COMMIT WORK 语句的返回码。

以下消息指示有一个参与者执行了启发式回滚:
-698 Inconsistent transaction. Number and names of servers rolled back.

检查数据库服务器消息日志文件的消息。
如果由于参与数据库服务器上的启发式决策导致有可能出现数据库不一致,那么协调
者的数据库服务器消息日志文件中会出现以下消息:
Mixed transaction result. (pid=nn user=user_id)
无论何时返回错误 -698,均会写入该消息。与该消息相关联的是事务回滚所涉及的参
与者数据库服务器的列表。这是完整的列表。 如果大量参与者回滚了该事务,那么
与 -698 错误消息一起创建的列表可能会被截断。

检查每个参与者的逻辑日志。
如果至少一个参与者回滚了其工作片段并且一个参与者落实了其工作片段,那么事务
将不正确地实现。
确定分布式数据库是否包含不一致的数据
如果您确定事务是不一致地实现,您必须确定这种情况对您的分布式数据库系统意味着什
么。您尤其必须确定数据完整性是否受到影响。

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 512 -
无论何时当一个参与者回滚的工作片段与另一参与者更新的工作片段相关时,不一致实现
的事务就造成了问题。不能使用 SQL 定义这些依赖性,因为分布式事务不支持引用多个
数据库服务器上数据的约束。仅当数据已在两个独立事务中更新时,该工作片段才是独立
的(不存在相关性)。否则,就认为该工作片段是有相关性的。
在您继续之前,请考虑导致该错误的事务。更新的数据段和回滚的数据段是否互相相关?
单个事务可能会由于其他原因(而不是维护数据完整性)而包含多次更新。 例如,以下
是三种可能的原因:

减少的事务开销

简化的编码

程序员喜好
并验证每个假设已落实事务的数据库服务器实际修改了数据。只读数据库服务器可能会作
为已落实事务的参与者而列出。
如果不一致的事务没有导致数据完整性的违例,此时您就可以退出该过程。
获取逻辑日志记录中的信息
要确定数据完整性是否受到不一致实现的全局事务的影响,必须重建全局事务,并确定事
务的哪些部分已落实,哪些已回滚。使用 onlog 实用程序获取必要信息。过程如下:
1.
在包含 HEURTX 记录的参与者上重建事务。
a. 参与者数据库服务器逻辑日志是您进行信息搜索的开始点。日志中的每条记录
均有本地事务标识号 (xid)。获取 HEURTX 记录的 xid。
b. 使用本地 xid 定位所有相关联的日志记录,这些记录作为该工作片段的一部分
而回滚。
2.
确定哪一数据库服务器是充当全局事务的协调者。
a. 查找参与者上包含相同本地 xid 的 PREPARE 记录。 PREPARE 记录为该参
与者标记了两阶段落实协议的起点。
b. 使用 onlog -l 选项获取 PREPARE 记录的详细输出。
该记录包含全局事务标识 (GTRID) 和协调数据库服务器的名称。有关 GTRID
的信息,请参阅获取全局事务标识。
3.
从协调者日志获取其他参与者的列表。
a. 检查协调者数据库服务器上的日志记录。 找到 BEGPREP 记录。
b. 检查 BEGPREP 记录的详细输出。
如果该记录中 GTRID 的前 32 字节与参与者的 GTRID 相匹配,那么
BEGPREP 记录是同一全局事务的一部分。请注意,BEGPREP 详细输出的
ASCII 部分中显示的参与者。
4.
重建每个参与者上的事务。

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 513 -
a. 在每个参与者数据库服务器上,读取逻辑日志以找到包含与该事务关联的
GTRID 的 PREPARE 记录,并获取该参与者执行的工作片段的本地 xid。
b. 在每个参与者数据库服务器上,使用本地 xid 定位所有与该事务(已落实或已
回滚)相关联的逻辑日志记录。
在您遵循该过程之后,您将知道事务的所有参与者是哪些、分配给每个参与者哪些工作片
段以及每个工作片段是已回滚还是已落实。根据该信息,您可以确定独立操作是否影响了
数据完整性。
获取全局事务标识
当全局事务开始时,它会接收到称为全局事务标识 (GTRID) 的唯一标识号。 GTRID 包
含协调者的名称。GTRID 已写入协调者的 BEGPREP 逻辑日志记录以及每个参与者的
PREPARE 逻辑日志记录。
要查看 GTRID,请使用 onlog -l 选项。GTRID 在记录的数据部分中偏移了 20 字节,长
为 144 字节。以下示例显示 BEGPREP 记录的 onlog -l 输出。协调者为 chrisw。
4a064 188 BEGPREP 4 0 4a038 0 1
000000bc 00000043 00000004 0004a038 .......C .......8
00087ef0 00000002 63687269 73770000 ..~..... chrisw..
00000000 00000000 00000000 00087eeb ........ ......~.
00006b16 00000000 00000000 00000000 ..k..... ........
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000001 6a756469 74685f73 ........ judith_s
6f630000 736f6374 63700000 oc..soct cp..
协调者上的 BEGPREP 记录与参与者(这些参与者是同一全局事务的一部分)上的
PREPARE 记录的 GTRID 的前 32 字节相同。例如,将以下示例中 PREPARE 记录的
GTRID 与上一个示例中 BEGPREP 记录的 GTRID 相比较。
c7064 184 PREPARE 4 0 c7038 chrisw
000000b8 00000044 00000004 000c7038 .......D ......p8
00005cd6 00000002 63687269 73770000 ...... chrisw..
00000000 00000000 00000069 00087eeb ........ ...i..~.
00006b16 00000000 00000010 00ba5a10 ..k..... ......Z.
00000002 00ba3a0c 00000006 00000000 ......:. ........
00ba5a10 00ba5a1c 00000000 00000000 ..Z...Z. ........

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 514 -
00ba3a0e 00254554 00ba2090 00000001 ..:..%ET .. .....
00000000 00ab8148 0005fd70 00ab8148 .......H ...p...H
0005fe34 0000003c 00000000 00000000 ...4...< ........
00000000 00ab80cc 00000000 00ab80c4 ........ ........
00ba002f 63687269 73770000 00120018 .../chrisw......
00120018 00ba0000 ........
确定是否需要执行操作来更正情况
如果不一致的事务创建了不一致的数据库,那么您可以有以下三个选项:

让联网数据库保持处于不一致状态。

除去落实事务之处受到的事务影响,从而回滚整个事务。

在回滚事务之处重新应用事务的影响,从而落实事务。
如果事务未严重影响数据库数据,那么您可以让数据库保持处于不一致状态。如果正在执
行事务的应用程序可以继续按原状执行,并且您得出的决定是通过除去影响或重新应用事
务来将数据库返回至一致状态的成本(时间与工作量方面的成本)过高,您就可能会遇到
这种情况。
无需立即作出此决定。您可以使用以下段落中描述的方法来确定事务在更新哪些数据以及
哪些记录受到影响。
当您作决定时,请考虑到没有自动过程或实用程序可以执行已落实事务的回滚或可以落实
已回滚事务的一部分。以下段落描述如何浏览数据库服务器消息日志和逻辑日志以找到受
影响的记录。如果不具备详细的应用程序知识,那么仅凭消息不足以确定所发生的事件。
根据您的应用程序和系统的知识,您必须确定是回滚还是落实事务。您还必须对执行回滚
或落实的补偿事务进行编程。

本示例中,设定将数据中的NULL 值导出为'\tnull\\' (即一个水平制表符,4 个字母
null,和一个反斜线\),导出方法如下:
$ ./orato8a --user='ssbm/ssbm@maya' --table_name='message' --file='./message.tbl' --format=3
--field=';' --null_value='\tnull\\'
export columns: 3
export rows: 10
export time: 0 sec
process ok!
$ cat message.tbl
1;Tom;I am Tom
2;小明;HHHH"KKKK
3;Peter;Hello!Hello!
4;Yama;send mail
5;Hellen;
null\
6;
null\;
null\
7;Seven;a book store
8;MMEE;yes
9;George;Thank you.

GBase 8a MPP Cluster 产品手册
4 管理员指南
文档版本953(2022-04-10)
南大通用数据技术股份有限公司
551
10;Lastman;no message