FCLT#84628 Savepoint deadlock preventie

svn path=/Database/trunk/; revision=67963
This commit is contained in:
2025-02-12 16:13:02 +00:00
parent 808661add0
commit f69cdb8f82

View File

@@ -317,10 +317,14 @@ AS
-- Met behulp van imp_exchange.gelukt kunnen importregels bewaard worden, zodat mutaties
-- aan appointments die gefaald zijn, alsnog kunnen worden doorgevoerd. Betekenis waarden 'gelukt':
-- NULL = niet correct verwerkt in vorige import --> nogmaals proberen
-- NULL = niet correct verwerkt in vorige import --> nogmaals proberen (of gewoon 'verse' regels toch .. ?)
-- 1 = succesvol verwerkt in vorige import --> importregel verwijderen
-- 2 = er is in een latere import een nieuwere status van dezelfde appointment ingelezen,
-- dus deze importregel is outdated --> regel verwijderen
-- 3 = a. Delete gevolgd door een Create/Update (komt toch niet voor .. ?)
-- b. Delete van onbekende reservering (komt volgens mij ook niet meer voor, wordt afgevangen in de asp-code)
-- 4 = Dit betreft een reservering die buiten het geconfigureerde datum-interval valt (die komt hier toch ook niet meer, de subscription luistert alleen naar changes binnen dit interval)
-- 5 = Regels die gaan over de res_ruimte als deelnemer
PROCEDURE import_exchange (p_import_key IN NUMBER, p_days_from IN NUMBER DEFAULT 0, p_days_to IN NUMBER DEFAULT 90)
IS
c_fielddelimitor VARCHAR2 (1) := ';';
@@ -385,14 +389,30 @@ AS
-- We willen mislukte regels uit eerdere imports bewaren, zodat we die nog eens kunnen proberen.
-- Alle correct verwerkte importregels krijgen een vlag, dus die gooien we weg.
-- Deletes die al deleted zijn, zijn schijnbaar al gelukt
DELETE FROM exc_import
WHERE gelukt IS NOT NULL
OR ( modifier = 'D'
AND EXISTS
(SELECT 1
FROM res_rsv_ruimte
WHERE res_rsv_ruimte_verwijder IS NOT NULL
AND res_rsv_ruimte_externnr = appt_id || '|' || recur_id));
BEGIN
FOR r
IN (SELECT exc_import_key
FROM exc_import e
WHERE gelukt IS NOT NULL
OR (SELECT fac_import_datum_gelezen
FROM fac_import
WHERE fac_import_key = e.fac_import_key) <
SYSDATE - 1 / 24 -- Regels ouder dan 1u hoeven we ook nooit meer opnieuw te proberen
OR ( modifier = 'D'
AND EXISTS
(SELECT 1
FROM res_rsv_ruimte
WHERE res_rsv_ruimte_verwijder
IS NOT NULL
AND res_rsv_ruimte_externnr =
appt_id || '|' || recur_id))
FOR UPDATE
SKIP LOCKED) -- Dan doen we deze later wel, geen haast
LOOP
DELETE FROM exc_import
WHERE exc_import_key = r.exc_import_key;
END LOOP;
END;
-- We gaan uit van een geldig bestand, mogelijk verandert dat onderweg
header_is_valid := 0;
@@ -1002,41 +1022,52 @@ AS
FROM fac_setting
WHERE fac_setting_name = 'msgraph_sync_level';
-- We doen niets met boekingen die buiten het geconfigureerde interval vallen
/*
Onderstaande UPDATE set het gelukt bitje naar een error-waarde (niet '1', want dat betekent succesvol voltooid)
Of NULL (= 'te verwerken') als er zich geen fout situatie voordoet
*/
UPDATE exc_import i
SET gelukt = 4
WHERE starttime > date_interval_end
OR endtime < date_interval_start;
-- En res_ruimtes als deelnemers, dat kan natuurlijk niet
UPDATE exc_import i
SET gelukt = 5
WHERE EXISTS
(SELECT 1
FROM res_ruimte
WHERE UPPER (res_ruimte_extern_id) = UPPER (att_mail));
-- Eerst verwijderen; dat scheelt onterechte "dirties" bij toevoegen
-- Bij verplaatsen naar een andere ruimte krijg je mogelijk een delete op de oude
-- ruimte; die voeren we niet uit. Ook deletes van niet-bekende appointments negeren we.
UPDATE exc_import i
SET gelukt = 3
WHERE modifier IN ('D')
AND EXISTS
(SELECT 1
FROM exc_import
WHERE modifier != 'D'
AND appt_id || '|' || recur_id =
i.appt_id || '|' || i.recur_id
AND seq_nr > i.seq_nr);
UPDATE exc_import i
SET gelukt = 3
WHERE modifier IN ('D')
AND NOT EXISTS
(SELECT 1
FROM res_rsv_ruimte
WHERE INSTR(res_rsv_ruimte_externnr, i.appt_id || '|') = 1);
SET gelukt =
CASE
WHEN EXISTS
(SELECT 1
FROM res_ruimte
WHERE UPPER (res_ruimte_extern_id) = UPPER (att_mail))
THEN 5 -- res_ruimtes als deelnemers, dat kan natuurlijk niet
WHEN i.fac_import_key = p_import_key
AND ( starttime > date_interval_end
OR endtime < date_interval_start)
THEN 4 -- We doen niets met boekingen die buiten het geconfigureerde interval vallen
WHEN modifier = 'D'
AND ( EXISTS
(SELECT 1
FROM exc_import
WHERE modifier != 'D'
AND appt_id || '|' || recur_id =
i.appt_id || '|' || i.recur_id
AND seq_nr > i.seq_nr)
OR NOT EXISTS
(SELECT 1
FROM res_rsv_ruimte
WHERE INSTR (res_rsv_ruimte_externnr,
i.appt_id || '|') =
1))
THEN 3 -- Dit zijn [D]eletes die nog gevolgd worden door nieuwere niet-[D]elete-regels of [D]eletes van niet bestaande Facilitor reserveringen
WHEN modifier IN ('C', 'U')
AND EXISTS
(SELECT 1
FROM exc_import
WHERE appt_id || '|' || recur_id =
i.appt_id || '|' || i.recur_id
AND fac_import_key !=
i.fac_import_key
AND seq_nr > i.seq_nr)
THEN 2 -- Er bestaan 2 = er is in een latere import een nieuwere status van dezelfde appointment ingelezen
ELSE
NULL -- 'te verwerken'
END
WHERE gelukt IS NULL
AND i.fac_import_key = p_import_key;
COMMIT; -- Cleanup
@@ -1170,33 +1201,6 @@ AS
COMMIT; -- de DELETE's
-- Omdat we entries die gefaald zijn 'bewaren', kan het zijn dat we voor <20><>n appointment
-- meerdere updates - of zelfs een delete - hebben. Dan zijn we alleen ge<67>nteresseerd in de
-- nieuwste, de rest kan genegeerd/weg. (Als we een nieuwere UPDate hebben, kan de originele
-- ADD/create ook weg; een update van een nog-niet-bestaande reservering zorgt voor aanmaken.)
-- Hoger seq_nr = latere mutatie in Exchange
UPDATE exc_import i
SET gelukt = 2
WHERE modifier IN ('C', 'U')
AND EXISTS
(SELECT 1
FROM exc_import
WHERE appt_id || '|' || recur_id =
i.appt_id || '|' || i.recur_id
AND fac_import_key != i.fac_import_key
AND seq_nr > i.seq_nr);
-- Hetzelfde voor deletes van niet-bestaande reserveringen
UPDATE exc_import i
SET gelukt = 2
WHERE modifier = 'D'
AND NOT EXISTS
(SELECT 1
FROM res_rsv_ruimte
WHERE res_rsv_ruimte_externnr = i.appt_id || '|' || i.recur_id);
COMMIT; -- Cleanup
-- Dan bestaande bijwerken, anders kan het gebeuren dat we op basis van een UPDATE
-- eerst een rsv_ruimte aanmaken en 'm daarna meteen proberen bij te werken.
-- TODO: is dat nog steeds zo met "gelukt = 1"?
@@ -1601,6 +1605,22 @@ AS
-- AND res_rsv_ruimte_externnr NOT LIKE '%|'||rec.recur_id||'|%'
AND res_rsv_ruimte_verwijder IS NULL;
-- We gaan deze afronden; zet vlag.
UPDATE exc_import
SET gelukt = 1
WHERE appt_id || '|' || recur_id =
rec.appt_id || '|' || rec.recur_id
AND fac_import_key = p_import_key
AND gelukt IS NULL;
IF (v_debug)
THEN
fac.imp_writelog (p_import_key,
'I',
v_aanduiding,
'gelukt=1');
END IF;
-- Er bestaan al deelreserveringen voor andere occurences van deze recurring appointment
-- Deelreservering binnen de bijbehorende res_reservering aanmaken
IF (v_count > 0)
@@ -1698,12 +1718,6 @@ AS
THEN
DELETE FROM res_reservering WHERE res_reservering_key = v_reservering_key;
END IF;
-- Pas het 'gelukt' bitje aan zodat we hem later niet weer opnieuw proberen
UPDATE exc_import
SET gelukt = 2
WHERE appt_id || '|' || recur_id =
rec.appt_id || '|' || rec.recur_id
AND gelukt IS NULL;
fac.imp_writelog (p_import_key,
'I',
@@ -1730,22 +1744,6 @@ AS
v_errorhint := 'Toevoegen bezoekers';
exc.importBezoekers(p_import_key, rec.appt_id, rec.recur_id, v_rsv_ruimte_key, date_interval_start, date_interval_end);
-- Succesvol afgerond; zet vlag.
-- TODO: komen we hier ook als er iets mis ging met de bezoekers?
UPDATE exc_import
SET gelukt = 1
WHERE appt_id || '|' || recur_id =
rec.appt_id || '|' || rec.recur_id
AND gelukt IS NULL;
IF (v_debug)
THEN
fac.imp_writelog (p_import_key,
'I',
v_aanduiding,
'gelukt=1');
END IF;
-- res_discipline achterhalen; alleen tracken voor EXCO en MC zalen
v_errorhint := 'res_discipline bepalen';