返回首页

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

更新日期:2024年09月11日

要防止同时访问智能大对象数据,
当打开智能大对象时,
数据库服务器取得对此数据的锁。
此智能大对象锁不同于以下种类的锁:

行锁
智能大对象上的锁不锁定智能大对象驻留其中的行。然而,如果您从行检索智能大
对象,且该行仍为当前的,则数据库服务器可能持有行锁以及智能大对象锁。在智
能大对象上持有锁,而不是在行上,因为许多列可能访问同一智能大对象数据。

在表的同一行中,不同智能大对象的锁
智能大对象上的锁不影响该行中的其他智能大对象。
下表展示智能大对象可支持的锁模式。
表 1. 智能大对象的锁模式
锁模式
用途
描述
lock-all
锁定整个智能大对象
指示锁请求适用于智能大对象的所有数据
byte-range
仅锁定智能大对象指定的
部分
指示锁请求仅适用于指定字节数的智能大对
象数据
当服务器打开智能大对象时,它使用下列信息来确定智能大对象的锁模式:

GBase 8s JDBC Driver 程序员指南
南大通用数据技术股份有限公司
- 162
-

智能大对象的访问模式
数据库服务器取得如下锁:

在共享模式下,当打开智能大对象来读取时(read-only)

在更新模式下,
当打开智能大对象来写时
(write-only、
read/write、
write/append)

当在智能大对象上实际执行写操作(或某其他更新)时,服务器将此锁升级
为排他锁。

当前事务的隔离级别
如果数据库表的隔离模式为 Repeatable Read,
则服务器不释放它在智能大对象上取
得的任何锁,直到事务结束为止。
在缺省情况下,服务器选择 lock-all 锁模式。
服务器保留该锁如下:

它持有共享模式锁和更新锁
(其尚未升级至排他锁)

直到发生下列事件之一为止:

智能大对象关闭

事务结束

显式的请求来释放锁(仅对于 byte-range 锁)

它持有排他锁,直到事务结束为止,即使关闭智能大对象也如此。
当发生前述条件之一时,服务器释放智能大对象上的锁。
重要: 即使智能大对象保持打开,在事务结束时,也会丢失锁。当服务器检测到智能大对象没
有活动的锁时,当首次发生智能大对象访问时,它自动地取得新的锁。它取得的锁是基于智能
大对象的原始访问模式的。
当当前事务终止时,服务器释放锁。然而,当执行下一需要锁的函数时,服务器再次取得
锁。
如果这不是期望的行为,
则服务器侧 SQL 应用程序可使用 BEGIN WORK 事务阻塞,
并在需要使用该锁的最后语句之后放置 COMMIT WORK 或 ROLLBACK WORK 语句。
byte-range 锁定
在缺省情况下,
当数据库服务器需要锁定智能大对象时,
它全部使用 lock-all 锁。
lock-all 锁
是一种 “全都或全不” 锁;也就是说,它们锁定整个智能大对象。当数据库服务器取得
排他锁时,只要持有锁,其他用户就不可访问智能大对象的数据。
如果此锁定对于应用程序的并发要求过于苛刻,则可使用 byte-range 锁定,而不使用
lock-all 锁定。以 byte-range 锁定,您可指定在智能大对象数据中锁定的字节范围。如果
其他用户访问该数据的其他部分,他们仍可获得自己的 byte-range 锁。
请使用 IfxSmartBlob 类中的 IfxLoLock() 方法,来指定 byte-range 锁定:
public long IfxLoLock(int lofd, long offset, int whence, long
range, int lockmode) throws SQLException

GBase 8s JDBC Driver 程序员指南
南大通用数据技术股份有限公司
- 163
-
要解锁该对象中的字节范围,请使用 IfxLoUnLock() 方法:
public long IfxLoUnLock( int lofd, long offset, int whence, long
range) throws SQLException
lofd 参数是由 IfxLoCreate() 或 IfxLoOpen() 方法返回的定位器文件描述符。offset 参数是从
开始的查找位置的偏移量。whence 参数标识开始的查找位置。在 智能大对象内的位置 中
的表中描述这些值。
range 参数指示在智能大对象内要锁定或解锁的字节数。
lockmode 参数指示要创建什么类型
的锁。这些值可为
IfxSmartBlob.LO_EXCLUSIVE_MODE 或 IfxSmartBlob.LO_SHARED_MODE。

可在连接或访问时更改数据库服务器会话的属性,而不更改会话所运行的应用程序。如果
不能修改应用程序的源代码来设置环境选项(或环境变量)或包含与会话相关的 SQL 语句
(例如,由于 SQL 语句包含从供应商处获得的代码)时,该操作很有帮助。
要更改会话的属性,可为各种数据库设计定制 sysdbopen()和 sysdbclose() 过程以支持
特定用户或 PUBLIC 组的应用程序。Sysdbopen() 和 sysdbclose() 过程可包含数据库服
务器在数据库打开或关闭时为用户或 PUBLIC 组执行的一系列 SET、
SET
ENVIRONMENT、
SQL
或 SPL 语句。
例如,对于 user1,可定义包含 SET
PDQPRIORITY、SET
ISOLATION
LEVEL、SET
LOCK
MODE、
SET
ROLE 或 SET
EXPLAIN
ON 语句的过程,无论何时 user1 使用 DATABASE 或 CONNECT
TO 语句打开数据库时,这些过程都将执行。
Sysdbopen() 过程中由 SET ENVIRONMENT 语句指定的会话环境变量 PDQPRIORITY 和
OPTCOMPIND 的任何设置都将在整个会话期间保持。对于常规过程非持久的 SET
PDQPRIORITY 和 SET ENVIRONMENT OPTCOMPIND 语句,在 sysdbopen() 过程包含它们时将
保持。
当作为过程所有者的用户从数据库断开连接时,将运行 user.sysdbclose() 过程(或者此
时将运行 PUBLIC.sysdbclose(),
前提是此过程存在且当前用户不具有任何 sysdbclose()

GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 20 -
过程)。
在定制 sysdbopen() 和 sysdbclose() 过程中,
如果在不符合 ANSI 标准的数据库中调用
了例程,那么 GBase 8s 将不会忽略 UDR 所有者的名称。
有关更多信息,请参阅配置会话属性和《GBase 8s SQL 指南:语法》。
配置会话属性
只有 DBA 或 gbasedbt 用户可以在 SQL 的 ALTER PROCEDURE、ALTER ROUTINE、CREATE
PROCEDURE、CREATE PROCEDURE FROM、CREATE ROUTINE FROM、DROP PROCEDURE 或 DROP
ROUTINE 语句中创建或更改sysdbopen()或 sysdbclose()。
可在连接或访问时设置更改会话属性的 sysdbopen() 过程,而不更改会话运行的应用程
序。如果不能修改应用程序的源代码来设置环境选项(或环境变量)或包含与会话相关的
SQL 语句(例如,由于 SQL 语句包含从供应商处获得的代码)时,该操作很有帮助。
要设置 sysdbopen() 和 sysdbclose() 过程以配置会话属性,请执行以下操作:
1.
将 IFX_NODBPROC 环境变量设置为任何值
(包括 0)
以使数据库服务器绕过并阻
止 sysdbopen() 或 sysdbclose() 过程的执行。
2. 编写 CREATE PROCEDURE 或 CREATE PROCEDURE FROM 语句以定义特定用户或
PUBLIC 组的过程。
3. 测试过程(例如,通过使用 EXECUTE PROCEDURE 语句中的 sysdbclose())。
4. 取消设置 IFX_NODBPROC 环境变量以使数据库服务器能够运行 sysdbopen() 或
sysdbclose() 过程。
示例
以下过程设置特定用户的角色和 PDQ 优先级:

create procedure oltp_user.sysdbopen()

set role to oltp;

set pdqpriority 5;

end procedure;
以下过程设置 PUBLIC 组的角色和 PDQ 优先级:

create procedure public.sysdbopen()

set role to others;

set pdqpriority 1;

end procedure
有关更多信息,请参阅《GBase
8s
SQL 指南:语法》中有关 sysdbopen() 和sysdbclose()
的信息。


GBase 8s 管理员指南
南大通用数据技术股份有限公司
- 21 -

功能
控制增量同步时delete 和update 是否允许primary key 的值为空。
默认值为0,即如果delete 和update 时primary key 的值为空则报错;
值为1时,
增量同步delete和update允许primary key的值为空,
这时kafka consumer
会正常进行同步,但是不保证同步结果与原数据库完全一致。
举例:
update t1 set A=2 where primarykey=1;
update t1 set A=2 where A=1;
{
"table":"BDTEST.T1",
"op_type":"U",
"op_ts":"2022-01-16 09:32:33.705303",
"current_ts":"2022-01-16T17:32:36.839000",
"pos":"00000000030000002612",
"primary_keys":{"A"},
"before":{
"A":1
}
"after":{
"A":2
}
}