Se più istanze dello stesso codice sono in esecuzione su server diversi, vorrei utilizzare un database per assicurarsi che un processo non viene avviato su un server, se è già in esecuzione su un altro server.Come si usa un database per gestire un semaforo?
Probabilmente potrei venire con alcuni comandi SQL utilizzabili che hanno utilizzato l'elaborazione delle transazioni Oracle, i latch o qualsiasi altra cosa, ma preferirei trovare qualcosa che sia stato provato e vero.
Anni fa uno sviluppatore che era un wiz SQL aveva una singola transazione SQL che prendeva il semaforo e restituiva true se lo otteneva e restituiva false se non lo otteneva. Poi alla fine del mio processo, avrei bisogno di eseguire un'altra transazione SQL per rilasciare il semaforo. Sarebbe bello, ma non so se è possibile che un semaforo supportato da database abbia un time-out. Sarebbe un enorme vantaggio avere un timeout!
EDIT:
Ecco quello che potrebbe essere alcuni comandi SQL praticabili, ma nessun timeout se non attraverso un hack job cron:
---------------------------------------------------------------------
--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.
---------------------------------------------------------------------
Per evitare scadenza manualmente i record, si può avere la serratura essere un timestamp. L'acquisizione del blocco imposta ora il timestamp. Per acquisire il blocco, la query per il blocco deve aggiungere una condizione WHERE locktime <(SYSDATE - timeToExpire). Quindi i fermi scadono automaticamente. – Glenn
Grazie Glenn ... il timestamp invece di Y/N è una bella aggiunta a quanto sopra. – Dale