Toon posts:

[PGSQL] Triggers, procedures en atomairiteit

Pagina: 1
Acties:

Verwijderd

Topicstarter
De topicuitleg kan een beetje abstract zijn, ik heb zelf de databases even niet bij de hand.

Het volgende hebben we: Een database met meerdere tables. De belangrijkste hiervan zijn table A en B. Table B bevat een Foreign Key naar A. Zodra in A iets wordt toegevoegd wordt via een trigger een waarde in B toegevoegd die hoort bij de waarde uit A.

Dit werkt allemaal. Nu komt het echter nogal vaak voor dat er heel vaak dezelfde waarde uit B moet worden gebruikt in een hele rits andere tabellen. Om dit makkelijker te maken hebben we in plpgsql een procedure gemaakt die eerst de waarde in A invoert en dan de waarde uit B die uit de trigger komt toevoegt in C, D, enz.
Wat blijkt nu: deze trigger wordt pas uitgevoerd als de hele functie klaar is. Aan de ene kant is het logisch aangezien de procedure een atomair geheel is, aan de andere kant is het net zo logisch om de trigger deel van de procedure te laten zijn.
We hebben al zitten zoeken naar mogelijkheden om de trigger alvast "af te laten gaan", maar hier lijkt niet zo heel veel over te vinden. Een mogelijke oplossing is om de query van de trigger gewoon zelf even uit te voeren binnen de procedure (en de foutmelding over key die al bestaat als de procedure is afgelopen en de trigger het opnieuw probeert). Zoiets hoort toch ook netter te kunnen?

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Als het geheel atomair moet zijn, waarom begin je ervoor niet een transactie die je aan het eind danwel commit danwel rollbacked? Daar zijn ze tenslotte o.a. voor, om atomaire groepen queries aan te duiden.

Daarnaast bestaan er 'before' en 'after' triggers, maar de before werken vast niet zo best bij inserts als je foreign keys naar het dan-nog-niet bestaande record wilt hebben :)

[edit]
Of is je probleem dat de trigger op B pas uitgevoerd wordt na de hele transactie die ook C en D omvat?

[ Voor 13% gewijzigd door ACM op 21-01-2006 17:23 ]


  • jochemd
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Gebruik je een BEFORE of een AFTER trigger?

Verwijderd

Topicstarter
Een beetje late reactie, ben even een paar dagen weggeweest

@jochemd: het is een after trigger, hij heeft immers de vers toegevoegde waarde nodig.

@ACM: Dit is hoe de hele transactie eruit zou moeten zien:
code:
1
2
3
4
5
6
BEGIN PROCEDURE
  INSERT INTO A
  INSERT INTO B (via de trigger van A)
  INSERT INTO C
  INSERT INTO D
END PROCEDURE;

Postgresql probeert dit op de volgende manier uit te voeren:
code:
1
2
3
4
5
6
BEGIN PROCEDURE
  INSERT INTO A
  INSERT INTO C
  INSERT INTO D
END PROCEDURE;
INSERT INTO B (via de trigger van A)

  • jochemd
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Verwijderd schreef op vrijdag 27 januari 2006 @ 09:18:
Een beetje late reactie, ben even een paar dagen weggeweest

@jochemd: het is een after trigger, hij heeft immers de vers toegevoegde waarde nodig.
En met de NEW: notatie heb je die ook.
code:
1
2
3
4
5
6
BEGIN PROCEDURE
  INSERT INTO A
  INSERT INTO B (via de trigger van A)
  INSERT INTO C
  INSERT INTO D
END PROCEDURE;

Postgresql probeert dit op de volgende manier uit te voeren:
code:
1
2
3
4
5
6
BEGIN PROCEDURE
  INSERT INTO A
  INSERT INTO C
  INSERT INTO D
END PROCEDURE;
INSERT INTO B (via de trigger van A)
Dat is by design. Zoek maar naar de "deferred trigger queue".


Als je echt van mening bent dat een BEFORE trigger niet zou werken dan ben ik benieuwd naar de code.

Verwijderd

Topicstarter
jochemd schreef op vrijdag 27 januari 2006 @ 19:31:
Dat is by design. Zoek maar naar de "deferred trigger queue".
Dat zal ik eens gaan doen dan.
Als je echt van mening bent dat een BEFORE trigger niet zou werken dan ben ik benieuwd naar de code.
B heeft een Foreign Key naar A, als je een before trigger uitvoert bestaat die key nog niet
code:
1
ERROR:  insert or update on table B violates foreign key constraint xxx

  • jochemd
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Verwijderd schreef op maandag 30 januari 2006 @ 09:31:
[...]

B heeft een Foreign Key naar A, als je een before trigger uitvoert bestaat die key nog niet
code:
1
ERROR:  insert or update on table B violates foreign key constraint xxx
Dan moet je daar een deferred constraint van maken.
Pagina: 1