Chicken-Egg-Problem?? Daten anzeigen=> Debugger

hallo Leute…ich habe das Chicken-Egg Problem mal in ein Postgresql-Schema versucht einzubauen und kurz hat es auch funktioniert…

aber dann gab es plötzlich ziemliche Verzögerungen als ich mir die Datenbankausprägung anzeigen lassen wollte.
Dann habe ich nochmal alles gedroppt und neu erzeugt aber leider leider liefert er immer bei “select * from egg” 0 Datensätze obwohl die Tabellenstatistik 1 Datensatz enthält.
Wenn ich dann die PGAdmin-Funktion wähle “Daten anzeigen” rauscht er bei jeder Tabelle ab die im Schema ist und liefert:Unhandled exception at
0x00000000 in pgAdmin3.exe: 0xC0000005: Access violation reading location 0x00000000.
No symbols are loaded for any call stack frame. The source code cannot be displayed.

wenn man den debugger starten läßt.
ich habe schon vacuum analyze laufen lassen aber nix geht…neustart des rechners half auch nicht

Hier mein Ei-Schema:

set transaction isolation level serializable;

–drop table chicken cascade; notfalls droppen
–drop table egg cascade; notfalls droppen

CREATE TABLE chicken(cID INT PRIMARY KEY,eID INT); --Hühner-Table
CREATE TABLE egg(eID INT PRIMARY KEY,cID INT);-- Eier-Table

ALTER TABLE chicken
ADD CONSTRAINT chickenREFegg
FOREIGN KEY (eID) REFERENCES egg(eID)
INITIALLY DEFERRED DEFERRABLE;

ALTER TABLE egg
ADD CONSTRAINT eggREFchicken
FOREIGN KEY (cID) REFERENCES chicken(cID)
INITIALLY DEFERRED DEFERRABLE;

BEGIN;
INSERT INTO chicken VALUES(1, 2); – constraint not checked here
INSERT INTO egg VALUES(2, 1);
COMMIT; – but here => chicken and egg - Problem solved :wink:

hi,

hab dein beispiel auf meinem postgresql server (8.1.3) probiert und konnte kein problem feststellen. evtl hat dein server(-dienst) ne macke?!

findest du evtl fehlermeldungen im log?

cu tb.

Hallo, und danke für den Versuch mir zu helfen! Also ich habe am Wochenende ein bissel rumexperimentiert.

Ich hatte folgende PG-Version auf dem Rechner: postgresql-8.1.0-2.zip

Habe dann gemerkt, dass es eine neuere Version gibt und mir 8.1.3-1 heruntergeladen. Vor dem Insatllieren habe ich das alte PG deinstalliert, den DB-User gelöscht und das PG-Verzeichnis ebenfalls gelöscht. Dann habe PG 8.1.3-1 neu installiert.

Ein DB erzeugt eine Tabelle erzeugt … gleiches Problem… hmmm nun wurde ich stutzig bzw. ängstlich :slight_smile:
Service gestopppt gestartet reboot etc. was man so macht… keine Änderung…

Kurz wie habe ich das Problem gelöst?
Um Zeit zu sparen habe ich einfach ein kürzlich angelegtes Windows-Image wiederhergestellt, die deinstallations-installationsprozedur wiederholt und es hat geklappt. Das Ei-Schema lebt nun unter 8.1.3-1 :wink:

Die Ursache war glaube ich, dass ich irgendwann mal beim Schema erzeugen nur das COMMIT aktiv hatte, ich bin aber nie wieder in der Lage gewesen den Fehler zu reproduzieren, und die LOG-Dateien habe ich leider auch nicht mehr.

–BEGIN; –
INSERT INTO chicken VALUES(1, 2); – constraint not checked here
INSERT INTO egg VALUES(2, 1);
COMMIT; – but here => chicken and egg - Problem solved

Nebenbei bemerkt:
man muss das Ei und das Huhn nicht innerhalb einer expliziten Transaktion einfügen. Es funktionmiert auch so…

–set transaction isolation level serializable; – nicht nötig

–drop table chicken cascade; --notfalls droppen
–drop table egg cascade; --notfalls droppen
–drop table irgendwas cascade; --notfalls droppen

CREATE TABLE chicken(cID INT PRIMARY KEY,eID INT); --Hühner-Table
CREATE TABLE egg(eID INT PRIMARY KEY,cID INT);-- Eier-Table

ALTER TABLE chicken
ADD CONSTRAINT chickenREFegg
FOREIGN KEY (eID) REFERENCES egg(eID)
INITIALLY DEFERRED DEFERRABLE;

ALTER TABLE egg
ADD CONSTRAINT eggREFchicken
FOREIGN KEY (cID) REFERENCES chicken(cID)
DEFERRABLE INITIALLY DEFERRED;

–BEGIN; – nicht nötig
INSERT INTO chicken VALUES(1, 2); – constraint not checked here
CREATE TABLE irgendwas(cID INT PRIMARY KEY,eID INT); --Hühner-Table
—blabla hier kann viel passieren… nur wieviel??
INSERT INTO egg VALUES(2, 1);
–COMMIT; – but here => chicken and egg - Problem solved – nicht nötig

select * from chicken c join egg e on c.eID=e.eID
1;2;2;1

Hallo normi,

das Problem dürfte in erster Linie ein Problem des Betriebssytems gewesen sein.

Das bezweifele ich!

INITIALLY IMMEDIATE
INITIALLY DEFERRED

If a constraint is deferrable, this clause specifies the default time to check the constraint. If the constraint is INITIALLY IMMEDIATE, it is checked after each statement. This is the default. If the constraint is INITIALLY DEFERRED, > it is checked only at the end of the transaction> . The constraint check time can be altered with the SET CONSTRAINTS command.

Woher soll die Datenbank bei ausgeschalteten AUTOCOMMIT wissen, wann das Ende einer Transaktion ist, wenn die Befehle der Transaktion nicht zwischen BEGIN und COMMIT eingeschlossen sind?



mfg

fristo

Also ich habe erstmal nach AUTOCOMMIT gesucht (da mir das neu war) und ich habe keine psqlrc-Datei. Nur eine “psqlrc.sample”, die mir sagt wie eine psqlrc-Datei anzulegen sein müsste. Demnach ist bei mir autocommit = on oder?

Zuminmdest nach dem Text der Doku:
Note: The autocommit-on mode is PostgreSQL’s traditional behavior, but autocommit-off is closer to the SQL spec. If you prefer autocommit-off, you may wish to set it in the system-wide psqlrc file or your ~/.psqlrc file.

nun ist also autocommit-on gesetzt.

Dann müsste sich doch eigentlich die DB beschweren, wenn ich Huhn und Ei gleichzeitig einfüge, ohne die Einfügeaktionen in eine Transaktion (BEGIN…COMMIT) zu setzen. Tut sie aber nicht :? Es geht ohne Probleme. Oder behandelt die DB mit dem Drücken auf den Play-Button in PGAdmin alle damit abgesendeten Befehle vielleicht als eine Transaktion?? Denn wenn ich folgendes mache:
Ei einfügen ‘play drücken’
Huhn einfügen ‘play drücken’ … dann gibt es Ärger, den hätte ich aber auch schon vorher erwartet.

Oder spielt diese “constraint check time” vielleicht noch eine Rolle die ich nicht verstehe?
“The constraint check time can be altered with the SET CONSTRAINTS command.” <-- und wie? Gibt es vielleicht eine Default-Zeitspanne in der gewartet wird, bis der Commit-Check gestartet wird wenn ich zuvor “DEFERRABLE INITIALLY DEFERRED” als Constraint im Foreign Key angebe?

Fragen über Fragen… :shock:

also nochmal wenn ich folgendes Querry absetzte klappt alles obwohl Autocommit = on gilt:

drop table chicken cascade; --notfalls droppen
drop table egg cascade; --notfalls droppen

CREATE TABLE chicken(cID INT PRIMARY KEY,eID INT);
CREATE TABLE egg(eID INT PRIMARY KEY,cID INT);

ALTER TABLE chicken
ADD CONSTRAINT chickenREFegg
FOREIGN KEY (eID) REFERENCES egg(eID)
INITIALLY DEFERRED DEFERRABLE;

ALTER TABLE egg
ADD CONSTRAINT eggREFchicken
FOREIGN KEY (cID) REFERENCES chicken(cID)
als INITIALLY DEFERRED;

INSERT INTO chicken VALUES(1, 2); --hier müsste er eigentlich schon meckern oder?
INSERT INTO egg VALUES(2, 1);–wenn man diese Zeile erstmal auskommentiert meckert er auch…

select * from chicken c join egg e on c.eID=e.eID

Hallo normi,

das in PostgreSQL AUTOCOMMIT defaultmäßig eingeschaltet ist, wissen die meisten Ein-/Umsteiger nicht, da sie nicht als erstes die Doku lesen. Jedes Produkt hat da seine Eigenarten und die sollte man schon vorab kennen. Viele wundern sich dann, dass Befehle das erwartete Ergebnis nicht bringen, da durch den AUTOCOMMIT bei einen vorhandenen Fehler alle bis dahin ausgeführten Aktionen wieder rückgängig gemacht werden.

Was macht AUTOCOMMIT? Es fügt automatisch am Anfang des Scripts den Befehl BEGIN und am Ende des Scripts den Befehl COMMIT aus. Dadurch wird das Script als eine TRANSAKTION behandelt, also wie ein einzelner Befehl.

Mal was zu Deiner FK-Konstruktion. Danach darf ein Huhn nur ein Ei legen. Die Art von Hühner kenn ich noch nicht, aber man lernt immer noch was dazu. In der Realität sieht das etwas anders aus. Wie Du dann das Huhn, spricht Datensatz bei eindeutiger ID, den Eiern zuordnen willst ist mir rätselhaft.

Zu deinem Problem: Solange Du den Code

CREATE TABLE chicken(cID INT PRIMARY KEY,eID INT); 
CREATE TABLE egg(eID INT PRIMARY KEY,cID INT); 

ALTER TABLE chicken 
ADD CONSTRAINT chickenREFegg 
FOREIGN KEY (eID) REFERENCES egg(eID) 
INITIALLY DEFERRED DEFERRABLE; 

ALTER TABLE egg 
ADD CONSTRAINT eggREFchicken 
FOREIGN KEY (cID) REFERENCES chicken(cID) 
als INITIALLY DEFERRED; 

INSERT INTO chicken VALUES(1, 2);
INSERT INTO egg VALUES(2, 1);

bei eingeschalteten AUTOCOMMIT ausführst, wird er immer funktionieren, zumal dass Du durch die Definition von INITIALLY DEFERRED DEFERRABLE festgelegt hast, dass die Überprüfung der FK’s am Ende der Transaktion erfolgen soll. Bei ausgeschalteten AUTOCOMMIT wird eine Fehlermeldung erfolgen, da der Code nicht mehr als eine Transaktion behandelt wird. Abhilfe ist hier das explizierte Einfügen von BEGIN und COMMIT.

Wenn das System “mekert (!)” hast Du mit Sicherheit einen Fehler gemacht und dann ist Nachdenken angesagt: Was habe ich da eigentlich gemacht?

Im Falle des Weglassens von

INSERT INTO egg VALUES(2, 1);

in Deinem Script, solltest Du mal Überlegen, wo das mekernde System den in dem Code

INSERT INTO chicken VALUES(1, 2);

angegebenen FK (eID = 2) finden soll?



Fragen über Fragen… :shock:

Hier kann das Lesen der Doku weiterhelfen.



mfg

fristo

Hallo fristo,

die genaue Funktionalität von AUTOCOMMIT ist mir jetzt klar geworden. Vielen Dank.

Ein Huhn darf nur ein Ei legen?
Das Schema sollte natürlich nicht die Realität darstellen. Ich gehe in diesem Schema davon aus, dass es keiner Eier gibt aus denen nicht ein Huhn schlüpft. Es werden in meiner Welt keiner Eier gegessen. Ich will also nur festhalten welches Huhn gehört zu welchem Ei und umgekehrt. Das ist nur ein didaktisches Beispiel.

Mir ist schon klar warum das System sich beschwert wenn ich eine der beiden Einfüge-Zeilen weglasse. Genau darum ging es ja letzendlich in meiner Frage.

Die Frage war ja warum PG keinen Fehler wirft, wenn beide Zeilen stehen. Die Antwort hast du mir gegeben: Weil Autocommit=on um den gesamt Codeblock den ich in PGAdmin III absetze ein “Beginn…Commit” setzt. AHA! oki Danke, eben genau diese Aussage habe ich wohl in der Doku übersehen.

Ich hatte es ursprünglich so verstanden dass Autocommit um jede einzelne Zeile ein “Begin…Commit” setzt.

Grüße Normi