Actuellement, j'implémente une procédure qui crée quelques lignes dans certaines tables liées à partir d'un modèle. Donc, ma procédure consiste en un SAVEPOINT
suivi de quelques instructions INSERT
sur différentes tables, et un curseur pour insérer d'autres lignes dans d'autres tables tout en faisant référence aux clés primaires nouvellement créées.Transaction atomique avec des déclencheurs BEFORE INSERT/UPDATE imbriqués
Chacune de ces tables a un déclencheur BEFORE INSERT/UPDATE défini qui a pour but de:
- Obtenir une nouvelle clé primaire à partir d'un séquenceur si elle est pas définie dans l'instruction INSERT (il y a des cas où Je dois régler le plus tard sur la touche primaire pour faire référence explicitement dans la même transaction)
- définir des valeurs par défaut si elles sont NULL
- définir les champs d'audit (last_change_date, last_change_user, etc ..)
La transaction échoue avec ORA-04091: table mute, déclenchement/fonction peut ne pas voir
Je comprends, que je pouvais résoudre ce, en déclarant TRANSACTION PRAGMA AUTONOME dans chaque déclenchement, mais mon opération ne plus être atomique, car c'est l'exigence que tous ces ensembles de données soient créés/insérés dans leur ensemble ou aucun d'entre eux.
Alors qu'est-ce que je fais de mal dans la conception de ma base de données?
MISE À JOUR: Voici le code du déclencheur
CREATE TRIGGER TRG_AUFTRAG_B_IU
BEFORE INSERT OR UPDATE
ON AUFTRAG
FOR EACH ROW
BEGIN
IF INSERTING THEN
IF :new.id is NULL or :new.id = 0 THEN
SELECT SEQ_AUFTRAG.nextval into :new.id from dual;
END IF;
IF :new.nummer is NULL or :new.nummer = 0 THEN
SELECT nvl(MAX(NUMMER),0)+1 INTO :new.nummer FROM AUFTRAG WHERE EXTRACT(YEAR from DATUM) = EXTRACT(YEAR from :new.DATUM);
END IF;
--DEFAULT Values
IF :new.BETR_GRENZWERTE_RELEVANT is NULL THEN
SELECT 0 INTO :new.BETR_GRENZWERTE_RELEVANT FROM dual;
END IF;
IF :new.DOKUMENTE_ABGELEGT is NULL THEN
SELECT 0 INTO :new.DOKUMENTE_ABGELEGT FROM dual;
END IF;
IF :new.EXT_ORG is NULL or :new.EXT_ORG < 1 THEN
SELECT 1 INTO :new.EXT_ORG FROM dual;
END IF;
:new.ERSTELLT_VON := nvl(:new.ERSTELLT_VON,user);
:new.ERSTELLT_DATUM := nvl(:new.ERSTELLT_DATUM,sysdate);
END IF;
:new.GEAENDERT_VON := user;
:new.GEAENDERT_DATUM := sysdate;
END;
Veuillez nous montrer le code de votre déclencheur. En fait, les actions que vous énumérez sont très typiques et utiles pour les déclencheurs, elles devraient fonctionner sans aucun problème. –
Il semble que vous exécutiez 'select' à partir de la même table dans le déclencheur. Sur la base de ce que vous dites que le déclencheur doit faire, il n'y a aucune exigence pour «sélectionner». Et vous avez raison - 'pragma autonome transaction 'n'est pas une solution à ce genre de problème. –
ah! Je pense que je vois déjà quel est le problème ... c'est le: nouveau: NUMMER part n'est-ce pas? Ceci est pour créer un numéro d'identification qui est une exigence de l'entreprise. Serait-ce une solution de le faire dans un AFTER INSERT TRIGGER? –