返回首页

gbase数据、南大通用产品文档:GBase8s锁作用域

更新日期:2024年09月11日


GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 239 -

您可将锁应用于整个数据库、整个表、磁盘页、单个行或索引键值。正被锁定的对象的大
小称之为锁的作用域(也称为锁颗粒度)。通常,锁的作用域越大,并发降得越低,但编
程越简单。
数据库锁
您可锁定整个数据库。打开数据库的操作在数据库的名称上放置一共享锁。使用
CONNECT、DATABASE 或 CREATE DATABASE 语句打开数据库。只要程序有一数据
库是打开的,则该名称上的共享锁防止任何其他程序删除该数据库或在其上放置排他锁。
下列语句展示您可能如何排他地锁定整个数据库:
DATABASE database_one EXCLUSIVE
如果没有其他程序已打开了那个数据库,则此语句成功。放置该锁之后,其他程序不可打
开该数据库,即使是读取也不可,因为它在该数据库名称上放置共享锁的尝试会失败。
仅当关闭该数据库时,
才释放数据库锁。
可使用 DISCONNECT 或 CLOSE DATABASE 语
句来显式地执行那个操作,或通过执行另一 DATABASE 语句来隐式地执行。
由于锁定数据库导致那个数据库中的并发降低为零,因此,它使得编程非常简单;不可发
生并发效果。然而,仅当其他程序不需要访问时,才应锁定数据库。在非高峰期间,对数
据进行大量更改之前,通常使用数据库锁定。

表锁
您可锁定整个表。在某些情况下,数据库服务器自动地执行此操作。您还可使用 LOCK
TABLE 语句来显式地锁定整个表。
LOCK TABLE 语句或数据库服务器可放置下列类型的表锁:
共享锁
任何用户都不可写表。在共享模式下,数据库服务器在表上放置一个共享锁,其通
知其他用户不可执行更新。此外,数据库服务器为每个更新了的、删除了的或插入
了的行添加锁。
排他锁
任何其他用户不可从该表读取或写该表。在排他模式下,数据库服务器仅在该表上
放置一个排他锁,不论它更新多少行。排他的表锁防止该表的任何并发使用,因此,
如果其他程序正在争夺对该表的使用,则可严重影响性能。然而,当您需要更新表
中的大部分行时,请在表上放置排他锁。
使用 LOCK TABLE 语句来锁定表
事务告诉数据库服务器通过 LOCK TABLE 语句来使用表级别锁定。下列示例展示如何在
表上放置排他锁:
LOCK TABLE tab1 IN EXCLUSIVE MODE

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 240 -

下列示例展示如何在表上放置共享锁:
LOCK TABLE tab2 IN SHARE MODE
提示: 在提供更大的并发时,您可为数据库服务器设置隔离级别来获得与共享的表锁相同
的保护程度。
数据库服务器何时自动地锁定表
在数据库服务器对任何下列语句执行操作时,它总是锁定整个表:
ALTER FRAGMENT
ALTER INDEX
ALTER TABLE
CREATE INDEX
DROP INDEX
RENAME COLUMN
RENAME TABLE
完成该语句(或事务结束)会释放该锁。在某些查询期间也可自动地锁定整个表。
使用 ONLINE 关键字来避免表锁定
对于未以 IN TABLE 关键字选项定义的索引,当您使用 ONLINE 关键字来 CREATE 或
DROP 索引时,您可最小化索引了的表上的排他锁的持续时间。
在联机创建或删除索引时,不支持表上的 DDL 操作,但当发出了 CREATE INDEX 或
DROP INDEX 语句时,可完成并发了的操作。直到没有其他进程正在并发地访问该表时,
才创建或删除指定的索引。然后,短暂地保持锁来写与该索引相关联的系统目录数据。这
提高了系统的可用性,因为通过正在进行的会话或新会话仍可读该表。下列语句展示如何
使用 ONLINE 关键字来避免在使用 CREATE INDEX 语句时的自动表锁定:
CREATE INDEX idx_1 ON customer (lname) ONLINE;
然而,对于使用 IN TABLE 关键字选项定义的“表中”索引,在包括 ONLINE 关键字的
CREATE INDEX 或 DROP INDEX 操作期间,
该索引了的表保持锁定。
其他会话尝试访问
该锁定了的表时,会失败并发出这些错误之一:
107: ISAM error: record is locked.
211: Cannot read system catalog (systables).
710: Table (table.tix) has been dropped, altered or renamed.

行和键锁
您可锁定表的一行。在其他程序继续处理同一表的其他行时,程序可锁定一行或选择的多
行。

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 241 -

行和键锁定不是缺省的行为。当您创建表时,您必须指定行级别锁定。下列示例创建带有
行级别锁定的表:
CREATE TABLE tab1
(
col1...
) LOCK MODE ROW;
当您创建表时,
如果指定 LOCK MODE 子句,
则您可稍后使用 ALTER TABLE 语句来更
改锁定模式。下列语句将保留表上的锁定模式更改为页级别锁定:
ALTER TABLE tab1 LOCK MODE PAGE
在某些情况下,数据库服务器必须锁定不存在的行。要这样做,数据库服务器在索引键值
上放置一个锁。使用键锁与使用行锁一样。当表使用行锁定时,作为假想行上的锁来实现
键锁。当表使用页锁定时,在包含该键或如果存在则包含该键的索引页上放置一键锁。
当您插入、更新或删除键(当您插入、更新或删除行时,自动地执行)时,数据库服务器
在该索引的键上创建锁。
当您更新较少行数时,由于它们提高并发性,因此行和键锁通常提供最佳性能。然而,数
据库服务器在获取锁时会造成一些开销。
当通过排他锁来锁定表中的一行或多行时,对其他用户的影响部分地依赖于它们的事务隔
离级别。其隔离级别不是 Dirty Read 的其他用户可能遇到事务失败,这是由于在指定的时
限内,未释放了排他锁。
对于 Committed Read 或 Dirty Read 隔离级别操作,这些操作尝试访问那些并发的会话已
在其上设置了排他的行级别锁的表,为了降低锁定冲突的风险,可启用事务来读取锁定了
的行中数据的最近提交的版本,而不是等待提交或回滚设置该锁的那个事务。启用对排他
地锁定了的行的最后提交的版本的访问,可以采用几种方式来实现:

对于个别的会话,发出此 SQL 语句
SET ISOLATION TO COMMITTED READ LAST COMMITTED;

对于使用 Committed Read 或 Read Committed 隔离级别的所有会话,DBA 可将
USELASTCOMMITTED 配置参数设置为 'ALL' 或设置为 'COMMITTED READ'。

对于使用 Committed Read 或 Read Committed 隔离级别的个别的会话,任何用户
都可发出带有 'ALL' 或 'COMMITTED READ' 的 SET ENVIRONMENT
USELASTCOMMITTED 语句作为此会话环境选项的值。

对于使用 Dirty Read 或 Read Uncommitted 隔离级别的所有会话,DBA 可将
USELASTCOMMITTED 配置参数设置为 'ALL' 或设置为'DIRTY READ'。

对于使用 Dirty Read 或 Read Uncommitted 隔离级别的个别的会话,
任何用户都可
发出带有 'ALL' 或 'DIRTY READ' 的 SET ENVIRONMENT
USELASTCOMMITTED 语句作为此会话环境选项的值。

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 242 -

仅当行级别锁定生效时,而不是当另一会话持有对整个表的排他锁时,此 LAST
COMMITTED 才有用。
对于任何 LOCK TABLE 语句在其上应用表级别锁的任何表,
禁用
此特性。请参阅《GBase 8s SQL 指南:语法》 中的 SET ENVIRONMENT 语句的描述,
要获取关于对并发访问通过排他锁锁定其中一些行的表的此特性的更多信息,以及对于可
支持此特性的表的种类限制的更多信息,请参阅《GBase 8s 管理员参考手册》中的
USELASTCOMMITTED 配置参数的描述。

页锁
数据库服务器以称为磁盘页的单位存储数据。一个磁盘页包含一行或多行。在一些情况下,
最好锁定一个磁盘页,而不是锁定它上面的个别行。例如,对于要求更改大量行的操作,
您可能选择页级别锁定,因为行级别锁定(每行一锁)的性价比可能不高。
当您创建表时,如果您未指定 LOCK MODE 子句,则对于该数据库服务器的缺省行为为
页级别锁定。使用页锁定,数据库服务器锁定包含该行的整个页。如果您更新存储在同一
页上的若干行时,数据库服务器对该页仅使用一个锁。
为所有 CREATE TABLE 语句设置行锁或页锁模式
对于所有新创建的表,GBase 8s 允许您为单个用户(每会话)或为多个用户(每服务器)
将锁模式设置为页级别锁定或行级别锁定。您不再需要在每次使用 CREATE TABLE 语句
创建新表时指定锁模式。
如果您想要以特定的锁模式创建您的会话内的每个新表,则您必须设置
IFX_DEF_TABLE_LOCKMODE 环境变量。例如,对于要以锁模式行创建的您的会话内的
每个新表,请将 IFX_DEF_TABLE_LOCKMODE 设置为 ROW。要覆盖此行为,请使用
CREATE TABLE 或 ALTER TABLE 语句并重新定义 LOCK MODE 子句。
单用户锁模式
如果在您的会话中创建的所有新表都要求相同的锁模式,则设置单用户锁模式。请使用
IFX_DEF_TABLE_LOCKMODE 环境变量来设置单用户锁模式。例如,对于在您的会话内
创建的每一个新表都以行级别锁定来创建,请将 IFX_DEF_TABLE_LOCKMODE 设置为
ROW。要覆盖此行为,请使用 CREATE TABLE 或 ALTER TABLE 语句并重新定义
LOCK MODE 子句。要获取关于设置环境变量的更多信息,请参阅《GBase 8s SQL 参考
指南》。
多用户锁模式
通过为同一服务器上的所有用户指定锁模式,数据库管理员可使用多用户锁模式来创建更
大的并发。然后,任何用户在那台服务器上创建的所有表都会有相同的锁模式。要启用多
用户锁模式,请在启动数据库服务器之前设置 IFX_DEF_TABLE_LOCKMODE 环境变量,
或设置 DEF_TABLES_LOCKMODE 配置参数。
优先顺序的规则

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 243 -

CREATE TABLE 或 ALTER TABLE 的锁定模式有下列优先顺序的规则,
按从最高优先顺
序到最低的顺序罗列:
1. 使用 LOCK MODE 子句的 CREATE TABLE 或 ALTER TABLE SQL 语句
2. 单用户环境变量设置
3. 在该服务器环境中的多用户环境变量设置
4. 配置文件中的配置参数
5. 缺省行为(页级别锁定)

稀疏索引锁
当您将索引的锁模式从常规的更改为稀疏的锁模式时,在该索引上要求索引级别的锁,而
不是项级别锁或页级别锁,这些是常规的锁。此模式减少索引上的锁调用的数目。
当您知道不会更改索引时,请使用稀疏索引模式;即,当在该索引上执行只读操作时。
请使用常规的锁模式来使数据库服务器在必要时在索引上放置项级别锁或页级别锁。当频
繁地更新索引时,请使用此模式。
当数据库服务器执行命令来将锁模式更改为稀疏的时,
在命令期间它需要在表上的排他锁。
在数据库服务器切换到稀疏锁模式之前,当前正在使用更细颗粒度的锁的任何事务都必须
完成。

智能大对象锁
CLOB 或 BLOB 列上的锁与行上的锁是分开的。仅当访问智能大对象时,才锁定它们。
当您锁定包含 CLOB 或 BLOB 列的表时,不锁定智能大对象。如果访问是为了写,则以
更新模式锁定智能大对象,且当实际的写发生时,将该锁提升为排他的。如果访问是为了
读,则以共享的模式锁定智能大对象。数据库服务器识别事务隔离模式,因此,如果设置
Repeatable Read 隔离级别,则在事务结束之前,数据库服务器不释放智能大对象读锁。
当数据库服务器检索行并更新该行指向的智能大对象时,在更新它期间,仅排他地锁定智
能大对象。
字节范围锁
您可锁定智能大对象的字节范围。字节范围锁允许事务有选择地仅锁定访问的那些字节,
因此,写用户和读用户可同时访问同一智能大对象中不同的字节范围。
要获取关于如何使用字节范围锁的信息,请参阅您的《GBase 8s 性能指南》。
字节范围锁支持死锁检测。要获取关于死锁检测的信息,请参阅 处理死锁。


GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
70

GBA-02IS-0003
错误码
错误标识
错误信息
GBA-02IS-0003

alloc: %s
错误出现原因
分配insert 内存错误

GBase 8a MPP Cluster 产品手册
7 附录
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1631
分析与建议
可能的原因是:
内存不足,
可以利用top 查看内存是否有剩余,
可在释放足够内
存后重试一次