アプリケーションロック

(8.0.22)
https://recruit.gmo.jp/engineer/jisedai/blog/mysql-get-lock/


select processlist_id,thread_id from performance_schema.threads
where processlist_id = connection_id()
;

drop procedure proc1;

delimiter //
create procedure proc1()
begin
declare res int;
start transaction;
select get_lock('test', -1) into res;
if res = 1 then
update tab1 set col1 = col1 + 1;
do sleep(60);
do release_lock('test');
end if;
commit;
end
//
delimiter ;

call proc1();


-- ロック確認


select * from performance_schema.data_locks
where thread_id in (96,99)
order by thread_id,lock_mode
;

select * from performance_schema.metadata_locks
where owner_thread_id in (96,99)
order by owner_thread_id,object_type
;

select is_used_lock('test');

※コミットしてもロックは解放されない
※同一名称で複数回ロック取得すると実行した回数分のロックが取得される

 

(19c)

select sys_context('userenv','sid') from dual;


declare
ret integer;
begin
ret := dbms_lock.request( id => 12345, lockmode=>dbms_lock.x_mode );
if ret in (0,4) then
update tab1 set col1 = col1 + 1;
dbms_lock.sleep(60);
ret := dbms_lock.release( id => 12345 );
end if;
commit;
end;
/

-- ロック確認

select * from v$lock
where sid in (15,471)
order by sid,type
;

※デフォルトではコミットしてもロックは解放されない(パラメータ「release_on_commit」で制御可能)
※同一名称で複数回ロック取得しても重複してロック取得されることはない

 

(13)
勧告的ロック

select pg_backend_pid();

do $$
declare
ret boolean;
i bigint;
begin
ret = false;
i = 0;
while (i <= 1000000 and ret != true) loop
select pg_try_advisory_xact_lock(12345) into ret;
perform pg_sleep(1);
i = i + 1;
end loop;
if ret = true then
update tab1 set col1 = col1 + 1;
perform pg_sleep(60);
end if;
commit;
end
$$
;

-- ロック確認
select l.pid, db.datname, c.relname, l.locktype, l.mode, l.granted
from pg_locks l
left join pg_class c on l.relation=c.oid
left join pg_database db on l.database = db.oid
where pid in (8411,8128)
order by l.pid,l.locktype
;


---- トランザクションレベルの排他勧告的ロックの場合
※コミットするとロックは解放される
トランザクションレベルの解放関数はないので同一名称で複数回ロック取得する意味はない


---- セッションレベルの排他勧告的ロックの場合
※コミットしてもロックは解放されない
※同一名称で複数回ロック取得すると実行した回数分のロックが取得される

 

セッションレベルの排他勧告的ロックを獲得
select pg_advisory_lock(33333);

セッションレベルの排他勧告的ロックを解放
select pg_advisory_unlock(33333);

トランザクションレベルの排他勧告的ロックの獲得
select pg_advisory_xact_lock(12345);

トランザクションレベルの排他勧告的ロックを解放
→関数なし

 

(2019)
https://elan.blog.ss-blog.jp/2011-02-02


select @@spid;

declare @ret int;
begin
begin transaction;
exec @ret = sp_getapplock @resource='test',@lockmode='exclusive',@lockowner='transaction';
if @ret >= 0
begin
update tab1 set col1 = col1 + 1;
waitfor delay '00:01:00';
exec sp_releaseapplock @resource='test',@lockowner='transaction';
end
commit;
end

 


-- ロック確認
select * from sys.dm_tran_locks
where request_session_id in (51,59)
order by request_session_id,resource_type
;

---- パラメータ「@lockowner」がtransactionの場合
※コミットするとロックは解放される
※同一名称で複数回ロック取得すると実行した回数分のロックが取得される


---- パラメータ「@lockowner」がsessionの場合
※コミットしてもロックは解放されない
※同一名称で複数回ロック取得すると実行した回数分のロックが取得される