![]() |
Datenbank: InterBase • Version: 7.5.1 • Zugriff über: dbExpress
InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constraint
Phänomen:
in eine 'Detail'-Tabelle wird per dynamisch erzeugtem SQL ein INSERT durchgeführt, der Primary Key wird über GEN_ID erzeugt, als Foreign-Key wird ein bestehender PK der Master-Tabelle eingefügt. Die dynamische Query wird über eine neu erzeugte TSQLQuery Instanz ausgeführt. Ab und zu schlägt das INSERT fehl mit der Meldung:
Code:
Die Constraint CONSTRAINT_FK ist definiert als
lock conflict on no wait transaction violation of FOREIGN KEY constraint "CONSTRAINT_FK" on table "DETAIL".
Code:
Dass ein INSERT mit einer "violation of FOREIGN KEY" fehlschlägt, obwohl der dabei verwendete FK existiert, ist schon eigenartig. In einem Screenshot der Anwendung ist der Master-Datensatz in einem DBGrid sichtbar.
FOREIGN KEY (FK_MASTER) REFERENCES MASTER (PK) ON DELETE CASCADE
Natürlich kann der Master-Datensatz gleichzeitig in anderen Transaktionen angezeigt und editiert werden, jedoch ändert sich sein PK dabei nicht. |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Wird der Master-Datensatz innerhalb der selben Transaktion wie der Detail-Datensatz geschrieben?
Wenn nicht, ist der Master-Datensatz bereits durch ein Commit bestätigt? |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Zitat:
|
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Der Isolationslevel wäre meine nächste Frage gewesen.
Wenn alles so zutrifft wie du es beschreibst, dürfte der FK-Fehler nicht auftreten. Ich würde prüfen, ob die von mir gemachten Annahmen auch immer so zutreffen. z.B. Ist das Commit wirklich gemacht worden? Hat Firebird vllt. doch Recht und die einzutragende Master-ID gibt es unter bestimmten Umständen doch nicht oder nicht mehr? Stimmt der Isolationslevel? Suche ich die Ursache an der richtigen Stelle? |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Was ich da irritierend finde ein "Lock" conflict bei insert.
1. Das kann vorkommen, wenn die DB kein Row Level Locking kann. Weiß nicht, wie das da bei IB und genau dieser Version aussieht. 2. Die zugehörige Fehlermeldung (seitens Firebird) spricht in der Erläuterung von Updates oder Deletes, nicht von Inserts. Daraus ergibt sich die Frage, fliegen hier nebenläufig noch andere Anweisungen rum? Ist das "dynamisch" generierte Statement tatsächlich korrekt? (Werden die ID verwendet (Master), die auch gewünscht sind? Oder bestehen beim Master oder Detail Tabelle andere Abhängigkeiten in Form von Triggern oder cascading constraints, die zu diesem Problem führen (bspw. Selbstreferenz, ...) (Quelle ![]() P.S.: Der Isolation level sollte m.E. ok sein. |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Zitat:
In 99,9 Prozent aller Fälle funktioniert das INSERT. Einen Fehler im Statement kann ich daher beherzt ausschliessen. Es gibt nur einen Trigger (BEFORE INSERT) in der Detail-Tabelle. Er sorgt für einen vorhandene Primary Key in der Detail-Tabelle, und füllt ein Feld mit dem aktuellen Usernamen der Connection. if (new.detail_pk is null) then new.detail_pk = gen_id(gen_detail, 1); if (new.DB_USER_NAME is null) then new.DB_USER_NAME = user; Da das Problem nur selten auftritt, halte ich es für wahrscheinlich dass Aktionen die in einer anderen Transaktion durchgeführt werden - z.B. der MASTER Datensatz wurde in einer anderen Transaktion geändert, aber noch nicht comitted - verantwortlich sind. Ich schaue mal ob ich etwas reproduzierbares finde. |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Zitat:
Es ist reproduzierbar: * ich starte in einem Datenbankclient eine Transaktion, ändere einen Wert (natürlich nicht den PK!) im Master, aber führe kein COMMIT durch * ich führe im Programm (andere Transaktion) das INSERT in der Detail-Tabelle aus * und: die Fehlermeldung erscheint Schlussfolgerung: Detail-INSERTs sind nur bei geschlossenen Transaktionen auf den MASTER möglich. Nächste Frage ist, ob das immer, nicht nur bei diesem Tabellenpaar auftritt... |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Macht Ihr denn da im Programm explizite Transaktionsanweisungen?
Also Connection.BeginTrans oder irgendsowas- weiß nicht mehr wie das da genau genannt wird? Die Frage wäre auch glaub ich nicht so sehr, was geändert wird, sondern ab welchem Moment die Sperre gesetzt wird und ob es nur eine Schreibsperre oder sogar eben Lesesperre wäre (das Insert verlangt ja per Definition durch FK Constraint nur die Existenz des Mastersatzes). Also macht Ihr explizit was per Code beim Ändern des Masters oder wenn nicht, welche Sperren setzt der Server und wann genau. Mit "rumfliegen" meinte ich zunächst nur in der gleichen Sitzung (nicht unbedingt Transaktion). Wenn Ihr fachbedingt Änderung an gleichen Datensätzen aus unterschiedlichen Sitzungen vornehmt, muss man sich das natürlich alles genauer ansehen. Oder entsteht das (Phänomen) nur, weil ggF. ein User das Programm mehrfach laufen hat und mit mehreren Intanzen des Programms am gleichen Fall arbeitet? Ps.: Achso, Du machst die Änderung im gleichen Programm/Sitzung? |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Zitat:
Mit einem anderen SQL Tool (IBExpert) habe ich das ganze reproduziert, sowohl im konkreten Master-Detail Tabellenpaar das die Fehlermeldung erzeugte, als auch in einem ähnlichen Master-Detail Paar. Das Verhalten tritt dort auch auf. In IBExpert habe ich dazu zwei SQL Editor Fenster geöffnet, d.h. UPDATE aus Master und INSERT in Detail erfolgen in verschiedenen Transaktionen. Nun wage ich zu folgern (zumindest für InterBase 7.5): INSERTs in eine Detailtabelle, die per Foreign-Key Constraint mit einer Mastertabelle verknüpft sind, schlagen fehl, wenn am Mastersatz Änderungen gemacht wurden, für die noch kein COMMIT erfolgte |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Zitat:
sonst könntest du dein Detail nicht committen, da der Master ja mit Rollback wieder verworfen werden könnte. |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Zitat:
Natürlich könnte in der selben Transaktion, die das Update im Master vornimmt, auch ein DELETE des Master-Satzes stattfinden und nach dem COMMIT der Satz für andere Transaktionen unsichtbar werden. Beim Isolationslevel READ COMITTED würde ich aber annehmen, dass erst nach dem COMMIT der Änderungen auf dem Master der Client diese sieht. Also sollte bis zum COMMIT des Masters der Client in der Lage sein ein INSERT auszuführen, da aus seiner Sicht der Master existiert. Aber immerhin ist nun klar, wie es von InterBase 7 gehandhabt wird. Der einzige Workaround (ausser dem etwas wackligen "so lange versuchen, bis das INSERT klappt") den ich ausprobieren könnte wäre der Verzicht auf die Foreign Key Constraint in der Detailtabelle. Mich wundert nur, dass dieses Problem nicht öfter beobachtet wird. Vielleicht gibt es zu wenige InterBase Datenbanken, in denen mit Foreign Key Constraint gearbeitet wird. Oder neuere Versionen arbeiten etwas schmerzfreier. |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Zitat:
Ich vermute, dass Constraints relativ wenig genutzt werden, spätestens wegen Problemen wie diesem (oder weil der Entwickler sich noch an sowas erinnert, auch wenn es ein anderes / älteres System war). Hinzu kommt, dass eine fachliche Komponente mitschwingt. Wenn die Software irgendwelche Sachbearbeitung macht und das hängt an einer Vertragsnummer oder Rechnungsnummer oder so, ist ein Konflikt relativ unwahrscheinlich. Geht es um Produkt oder Bestelldaten, und es wird bspw. die items on stock property häufig geändert, dürften viel mehr solche Fälle auftreten. Ein filigranerer Sperrmechnismus würde auch helfen. Vielleicht geht es ja bei neueren Versionen. |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Zitat:
|
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Zitat:
Oder hast Du das bei den Querchecks von vorhin erst gar nicht "nachgeahmt"? Die Prüfung ist ja doppeltgemoppelt, der FK Constraint soll das ja abfackeln. Besser wäre hier wahrscheinlich, es knallen zu lassen bzw. die database exception zu fangen und zu behandeln (wie auch immer) |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Zitat:
Vielen Dank für die Anregungen und Tips! |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Clientseitig ist mir eingefallen, habe ich mal etwas in einem ähnlichen Zusammenhang implementiert, um ähnliche Probleme zu verhindern. Eine Monstermaske mit Master und mehreren Detaildatasets.
Man konnte anfangs einen neuen Mastersatz ungeposted stehen lassen und Details eintragen, bis zum post natürlich, der ging nicht, weil der Masterkey nicht da sein konnte. Ich habe dann schließlich so umgebaut, dass bei Verlassen (GUI) des Mastersatzes nachgefragt wurde, ob man nicht posten möchte. "Verlassen" kann dabei unterschiedlich komplex sein. Hilft natürlich nichts, wenn Dein Problem auf unterschiedlichen System basiert. Aber wenn es so ist wie es ist, spricht m.E. auch nichts dagegen, beim Posten (Fehlschlag) eine entsprechende Meldung auszugeben: "Der .. hat es seit 2h noch nicht geschafft, auf "Commit" zu drücken und blockiert alles, sie finden ihn in Büro xy 2.Etage.. ." ;) Naja so ähnlich |
AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai
Hallo,
Zitat:
Zitat:
Das obige Verhalten hatte ich seit FB1.5 nicht mehr beobachtet. Allerdings sind bei uns die Mastertabellen immer weit früher gefüllt als die Detailtabellen, und alles schick mit expliziten Transaktionen gekapselt. Ein Detail-Datensatz kann per Design bei uns nicht angelegt werden, bis der Master seine Transaktion abgeschlossen hat. Danach wird auf jeden Fall eine neue (Detail-)Transaktion gestartet. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:52 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz