gpt4 book ai didi

sql - 如何使用数据库来管理信号量?

转载 作者:行者123 更新时间:2023-12-04 10:55:51 25 4
gpt4 key购买 nike

如果同一代码的多个实例在不同的服务器上运行,我想使用数据库来确保进程不会在一台服务器上启动,如果它已经在另一台服务器上运行。

我可能会想出一些使用 Oracle 事务处理、闩锁或其他任何东西的可行 SQL 命令,但我宁愿找到一些已经尝试过的东西。

几年前,作为 SQL 专家的开发人员有一个 SQL 事务,该事务接受信号量并在得到信号量时返回 true,如果没有得到信号量则返回 false。然后在处理结束时,我需要运行另一个 SQL 事务来释放信号量。这会很酷,但我不知道数据库支持的信号量是否有可能超时。超时将是一个巨大的奖励!

编辑:

以下是一些可行的 SQL 命令,但除了通过 cron 作业 hack 之外没有超时:

---------------------------------------------------------------------
--Setup
---------------------------------------------------------------------
CREATE TABLE "JOB_LOCKER" ( "JOB_NAME" VARCHAR2(128 BYTE), "LOCKED" VARCHAR2(1 BYTE), "UPDATE_TIME" TIMESTAMP (6) );
CREATE UNIQUE INDEX "JOB_LOCKER_PK" ON "JOB_LOCKER" ("JOB_NAME") ;
ALTER TABLE "JOB_LOCKER" ADD CONSTRAINT "JOB_LOCKER_PK" PRIMARY KEY ("JOB_NAME");
ALTER TABLE "JOB_LOCKER" MODIFY ("JOB_NAME" NOT NULL ENABLE);
ALTER TABLE "JOB_LOCKER" MODIFY ("LOCKED" NOT NULL ENABLE);

insert into job_locker (job_name, locked) values ('myjob','N');
commit;

---------------------------------------------------------------------
--Execute at the beginning of the job
--AUTOCOMMIT MUST BE OFF!
---------------------------------------------------------------------
select * from job_locker where job_name='myjob' and locked = 'N' for update NOWAIT;
--returns one record if it's ok. Otherwise returns ORA-00054. Any other thread attempting to get the record gets ORA-00054.
update job_locker set locked = 'Y', update_time = sysdate where job_name = 'myjob';
--1 rows updated. Any other thread attempting to get the record gets ORA-00054.
commit;
--Any other thread attempting to get the record with locked = 'N' gets zero results.
--You could have code to pull for that job name and locked = 'Y' and if still zero results, add the record.

---------------------------------------------------------------------
--Execute at the end of the job
---------------------------------------------------------------------
update job_locker set locked = 'N', update_time = sysdate where job_name = 'myjob';
--Any other thread attempting to get the record with locked = 'N' gets no results.
commit;
--One record returned to any other thread attempting to get the record with locked = 'N'.

---------------------------------------------------------------------
--If the above 'end of the job' fails to run (system crash, etc)
--The 'locked' entry would need to be changed from 'Y' to 'N' manually
--You could have a periodic job to look for old timestamps and locked='Y'
--to clear those.
---------------------------------------------------------------------

最佳答案

您应该查看 DBMS_LOCK。本质上,它允许 Oracle 内部使用的入队锁定机制,但它允许您定义“UL”(用户锁定)的锁定类型。锁可以是共享的或独占的,并且请求获取锁或将锁从一种模式转换为另一种模式,支持超时。

我认为它会做你想做的。

希望有帮助。

关于sql - 如何使用数据库来管理信号量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9115684/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com