Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Race Conditions mit DBs vermeiden (https://www.delphipraxis.net/105895-race-conditions-mit-dbs-vermeiden.html)

yankee 1. Jan 2008 20:41

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:
INSERT INTO tabelle2 (tb1id) VALUES (42)
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
SQL-Code:
SELECT COUNT(*) FROM tabelle1 WHERE id=42
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.
Eine DB nehmen, die Fremdschlüssel beherscht, diese entsprechend definieren und alle Sorgen los sein?

mkinzler 1. Jan 2008 20:49

Re: Race Conditions mit DBs vermeiden
 
Solche Abhängigkeiten kann man im Datenbankmodell hinterlegen

generic 2. Jan 2008 06:38

Re: Race Conditions mit DBs vermeiden
 
mk wollte sagen: constrains in die datenbank und mit transaktionen arbeiten

hoika 2. Jan 2008 08:16

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:
Alter Table Tab2 Add Constraint FK_Tab2__Tab2Id
Foreign Key (Tab1Id) References Tab1(Id)
On Delete Cascade
Damit werden beim Löschen in Tab1 Referenzen in Tab2 automatisch gelöscht.


Die Syntax ist bei verschiedenen DBS aber verschieden.


Heiko

DeddyH 2. Jan 2008 08:18

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.

hoika 2. Jan 2008 09:07

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

yankee 2. Jan 2008 10:21

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 ;-).

hoika 2. Jan 2008 11:45

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

generic 4. Jan 2008 12:00

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 04:34 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