AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constraint
Thema durchsuchen
Ansicht
Themen-Optionen

InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constraint

Ein Thema von mjustin · begonnen am 24. Apr 2017 · letzter Beitrag vom 25. Apr 2017
Antwort Antwort
Seite 1 von 2  1 2      
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#1

InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constraint

  Alt 24. Apr 2017, 11:13
Datenbank: InterBase • Version: 7.5.1 • Zugriff über: dbExpress
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:
lock conflict on no wait transaction violation of FOREIGN KEY constraint "CONSTRAINT_FK" on table "DETAIL".
Die Constraint CONSTRAINT_FK ist definiert als
Code:
FOREIGN KEY (FK_MASTER) REFERENCES MASTER (PK) ON DELETE CASCADE
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.

Natürlich kann der Master-Datensatz gleichzeitig in anderen Transaktionen angezeigt und editiert werden, jedoch ändert sich sein PK dabei nicht.
Michael Justin

Geändert von mjustin (24. Apr 2017 um 11:16 Uhr) Grund: doppelten Text entfernt, code-tags
  Mit Zitat antworten Zitat
alex517

Registriert seit: 23. Nov 2004
Ort: Bernau b. Berlin
273 Beiträge
 
Delphi XE5 Enterprise
 
#2

AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai

  Alt 24. Apr 2017, 11:56
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?
Alexander
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#3

AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai

  Alt 24. Apr 2017, 12:03
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?
Die INSERTS sind in verschiedenen Transaktionen, der MASTER wird zeitlich lange vor dem DETAIL erzeugt und comitted. Der Client sieht den Master (z.B. wird er in einem DBGrid selektiert), der Benutzer startet per Knopfdruck das Detail-Insert. (Leere / Null FK Werte werden abgefangen). Isolationslevel ist READ COMITTED.
Michael Justin
  Mit Zitat antworten Zitat
alex517

Registriert seit: 23. Nov 2004
Ort: Bernau b. Berlin
273 Beiträge
 
Delphi XE5 Enterprise
 
#4

AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai

  Alt 24. Apr 2017, 12:32
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?
Alexander
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#5

AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai

  Alt 24. Apr 2017, 12:35
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 http://www.firebirdfaq.org/faq109/ -hab mir nicht die Mühe gemacht, nach original IB Doku zu suchen, ist also vielleicht irreführend, was da steht)

P.S.: Der Isolation level sollte m.E. ok sein.
Gruß, Jo
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#6

AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai

  Alt 24. Apr 2017, 13:05
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 http://www.firebirdfaq.org/faq109/ -hab mir nicht die Mühe gemacht, nach original IB Doku zu suchen, ist also vielleicht irreführend, was da steht)

P.S.: Der Isolation level sollte m.E. ok sein.
Da multi-user, fliegen einige andere Anweisungen rum. Die sind in anderen Prozessen, im aktuelle Prozess laufen keine Threads o.ä. mit Datenbankzugriff. Als weitere Absicherung prüft das Programm vor dem INSERT, ob der als FK einzutragende Wert tatsächlich in der MASTER Tabelle "sichtbar" ist (existiert).
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.
Michael Justin
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#7

AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai

  Alt 24. Apr 2017, 13:19
Daraus ergibt sich die Frage, fliegen hier nebenläufig noch andere Anweisungen rum?
Also so etwas

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...
Michael Justin
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#8

AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai

  Alt 24. Apr 2017, 13:28
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?
Gruß, Jo
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#9

AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai

  Alt 24. Apr 2017, 13:33
Macht Ihr denn da im Programm explizite Transaktionsanweisungen?
Nein, wir verwenden die Default-Transaktionen die von dbExpress verwaltet werden.

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
Michael Justin

Geändert von mjustin (24. Apr 2017 um 13:38 Uhr)
  Mit Zitat antworten Zitat
alex517

Registriert seit: 23. Nov 2004
Ort: Bernau b. Berlin
273 Beiträge
 
Delphi XE5 Enterprise
 
#10

AW: InterBase: lock conflict on no wait transaction violation of FOREIGN KEY constrai

  Alt 24. Apr 2017, 13:46
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
Das muss so sein (ist auch schon immer so),
sonst könntest du dein Detail nicht committen,
da der Master ja mit Rollback wieder verworfen werden könnte.
Alexander
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:22 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz