VastbaseG100

基于openGauss内核开发的企业级关系型数据库。

Menu

DBMS_LOCK

  • 提供多种锁模式,各模式都有自己的冲突列表。

  • 各个锁模式的含义及取值如下表:

名字 描述
nl_mode NULL 1
ss_mode Sub Shared,表示在一个对象的子部分上获取共享锁 2
sx_mode Sub Exclusive,表示在一个对象的子部分上获取独占锁 3
S_mode Shared,表示对整个对象获取共享锁 4
Ssx_mode Shared Sub Exclusive,表示整个对象已有共享锁,但是还要对某些字部份获取独占锁 5
X_mode Exclusive,表示对整个对象获取独占锁 6
  • 当要获取一个对象的锁时,如果这个对象的锁正被其他会话所持有,那么需要根据该对象的锁正被持有的模式以及当前要获取的锁的模式来判断本次是否能够成功获取,不同锁模式的冲突列表如下:
HELD MODE GET NL GET SS GET SX GET S GET SSX GET X
NL success success success success success success
SS success success success success success fail
SX success success success fail fail fail
S success success fail success fail fail
SSX success success fail fail fail fail
X success fail fail fail fail fail
  • 各函数如下:
函数名 参数类型 结果类型 描述
allocate_unique lockname varchar,OUT lockhandle varchar,expiration_secs integer varchar 为指定的锁名分配一个唯一的锁id
convert lockhandle varchar,id integer,lockmodeinteger,timeout integer integer 用于进行锁模式的转换
request id integer,lockhandle varchar,lockmode integer,timeout integer,release_on_commit boolean integer 请求一个指定模式的锁
release id integer,lockhandle varchar integer 用来显示释放由request函数占有的锁
sleep seconds double precision null 使session睡眠指定的时间
  • 函数输出返回值含义如下表所示:
返回值 request函数输出返回值含义描述 release函数输出返回值含义
0 success success
1 timeout
2 deadlock
3 parameter error parameter error
4 already own lock specified by id or lockhandle don't own lock specified by lockhandle
5 illegal lock handle illegal lock handle
CREATE OR REPLACE FUNCTION lock_test() RETURNS int AS $$
DECLARE
    v_ret int;
    v_name varchar(100) := 'test';
    v_handle varchar(100);
BEGIN
    dbms_output.enable();
    dbms_output.serveroutput(true);
    dbms_output.put_line('----- session start ------');
    select dbms_lock.allocate_unique(v_name, 2) into v_handle;
    v_ret := dbms_lock.request(v_handle, 6, 100, false);
    IF v_ret <> 0 THEN
        -- 获取锁失败
        dbms_output.put_line('--- lock request lock failed ---');
        RETURN v_ret;
    ELSE
        dbms_output.put_line('--- now reqeust lock success ---');
    END IF;
    -- 获取锁成功,此处添加请求业务逻辑
    dbms_lock.sleep(30);
    -- 执行完成,应该要释放掉锁
    IF v_ret = 0 THEN
        v_ret := dbms_lock.release(v_handle);
    END IF;
    RETURN v_ret;
END;
$$ LANGUAGE plpgsql;