![]() |
Datenbank: tut nichts zur Sache ;-) • Zugriff über: nur gedanklich :-P
Race Conditions mit DBs vermeiden
Hi @ll,
ich habe folgednes Problem: Eine Datenbank mit 2 Tabellen Tabelle 1: id INT ... Tabelle 2: tab1id INT ... Also jeder Datensatz aus Tabelle 2 bezieht sich auf einen Datensatz in Tabelle 1. In Tabelle 2 soll es keine Datensätze geben, deren Feld tab1id sich nicht auf eine id aus der Tabelle 1 bezieht. Jetzt will ich einen neuen Datensatz in Tabelle 2 einfügen. Die Tabelle 1 enthält aktuell nur einen Datensatz mit der id 42. Auf diesen soll sich der neue Datensatz aus Tabelle 2 beziehen. Mir ist auch klar, dass sich der neue Datensatz in Tabelle 2 auf den Datensatz mit der id 42 aus Tabelle 1 beziehen soll. Also könnte ich den neuen Datensatz einfach einfügen:
SQL-Code:
Jetzt habe ich aber das Problem, dass der Datensatz aus Tabelle 1 längst gelöscht sein könnte. Was tue ich um zu verhindern, dass der neue Datensatz eingefügt wird, wenn der Datensatz aus Tabelle 1 nicht mehr existiert? Einfach vorher nochmal mit
INSERT INTO tabelle2 (tb1id) VALUES (42)
SQL-Code:
prüfen, ob der Datensatz noch existiert? Dadurch wird es schonmal extrem unwahrscheinlich, dass ich mir das genannte Problem einhandle, weil der Datensatz aus Tabelle 1 gelöscht werden müsste nachdem ich geprüft habe ob er existiert und bevor ich den neuen Datensatz einfüge.
SELECT COUNT(*) FROM tabelle1 WHERE id=42
Eine DB nehmen, die Fremdschlüssel beherscht, diese entsprechend definieren und alle Sorgen los sein? |
Re: Race Conditions mit DBs vermeiden
Solche Abhängigkeiten kann man im Datenbankmodell hinterlegen
|
Re: Race Conditions mit DBs vermeiden
mk wollte sagen: constrains in die datenbank und mit transaktionen arbeiten
|
Re: Race Conditions mit DBs vermeiden
Hallo,
im konkreten Fall "Foreign Key" verwenden unter Firebird sieht das per SQL dann so aus.
SQL-Code:
Alter Table Tab2 Add Constraint FK_Tab2__Tab2Id
Foreign Key (Tab1Id) References Tab1(Id) 1. Es kann kein Datensatz in Tab2 angelegt werden, der nicht eine gültige Referenz zu Tab1 besitzt. 2. Es kann kein Datensatz in Tab1 gelöscht werden, wenn es noch Referenzen in Tab2 gibt. Für 2. gäbe es noch als Variante
SQL-Code:
Damit werden beim Löschen in Tab1 Referenzen in Tab2 automatisch gelöscht.
Alter Table Tab2 Add Constraint FK_Tab2__Tab2Id
Foreign Key (Tab1Id) References Tab1(Id) On Delete Cascade Die Syntax ist bei verschiedenen DBS aber verschieden. Heiko |
Re: Race Conditions mit DBs vermeiden
Die Möglichkeit, kaskadierend zu löschen, sollte man aber nur einsetzen, wenn man sich das reiflich überlegt hat.
|
Re: Race Conditions mit DBs vermeiden
Hallo,
jepp, das hatte ich vorausgesetzt ;) Es erleichtert bei Standard-Sachen enorm die Arbeit. Bsp. Table Config(Id) Table Config_Option (Id,ConfigId,OptionName,OptionValueS char) Lösche ich eine Konfiguration, sollen auch alle Optionen gelöscht werden. Einfache Aufgabe an eine DB. Heiko |
Re: Race Conditions mit DBs vermeiden
ok, danke, so werde ich es dann wohl weiterhin machen.
Mir ist nur aufgefallen, dass das Problem sehr häufig von Entwicklern ignoriert wird. Wenn man nur eine DB ohne Transaktionen zur Verfügung hat, hat man dann ja auch ein Problem ;-). |
Re: Race Conditions mit DBs vermeiden
Hallo,
ignoriert! jepp! Ich hatte mich mal mit ein paar Leuten unterhalten, die hatten mysql (Kann erst ab einer der 4er Transaktionen). Die sagten "Transaktionen, damit hatten wir uns noch nicht beschäftigt". Das Dumme ist halt, dass im DB-Unterricht sowas nur am Rande erwähnt wird. Heiko |
Re: Race Conditions mit DBs vermeiden
das mit mysql ist nicht so schlimm, da eh die version 5 aktuell ist.
um transaktionen und contrains/foreign key nutzen zu können musst du dann den innodb treiber für die tabellen nehmen. der isam treiber tut es nicht! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:34 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