Schrift
[thread]3629[/thread]

Datenbanktabelle sperren



<< |< 1 2 3 >| >> 22 Einträge, 3 Seiten
MartinR
 2005-10-07 12:45
#33672 #33672
User since
2004-06-17
305 Artikel
BenutzerIn
[default_avatar]
Hi,

ich habe eine Tabelle mit nur einer Spalte und nur einem Feld. Auf meine MySQL-DB greife ich über DBI zu.

Ich möchte nun mit einem Update dieses Feld um 1 erhöhen und dann gleich den neuen Wert mit Select auslesen.

Wie kann ich nun während dieser zwei Abfragen verhindern, dass ein weiterer (gleichzeitiger) Aufruf meines Skriptes die Ausgabe verfälscht?

Also diesen Vorgang verhindern:
- Update durch User 1 => neue ID = 5
- Update durch User 2 => neue ID = 6
- Select durch User 1 => Ergebnis = 6 (verfälscht)
- Select durch User 2 => Ergebnis = 6 (richtig)

Es soll also so laufen:
Tabelle sperren - Update - Select - Tabelle wieder freigeben

Oder hat jemand eine andere Idee?

Danke
pq
 2005-10-07 13:14
#33673 #33673
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
entweder mit LOCK TABLES oder, wenn die tabelle in InnoDB vorliegt, transaktionen.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
MartinR
 2005-10-10 13:36
#33674 #33674
User since
2004-06-17
305 Artikel
BenutzerIn
[default_avatar]
Hallo und Danke,

hätte ich auch selbst darauf kommen können.

Aber wie läuft es denn nun ab, wenn ein Zugriff auf eine gesperrte Tabelle erfolgt? Wartet der Prozess dann so lange bis die Sperre aufgehoben wird oder wird einfach abgebrochen?

Und was ist, wenn z.B. mein Perlscript nach dem lock aber noch vor dem unlock abschmiert. Bleibt die Tabelle dann gesperrt?\n\n

<!--EDIT|MartinR|1128936999-->
Taulmarill
 2005-10-10 13:44
#33675 #33675
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
bei gesperrten tabellen weiss ich das nicht so genau, aber bei transaktionen wartet er normalerweise bis die tabelle wieder frei wird, oder ein timeout verstrichen ist. imho währe hier ein transaktion auch sinniger.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
pq
 2005-10-10 14:20
#33676 #33676
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
eine transaktion ist auf jeden fall dann angebracht, wenn ohne sie die datenbank
im fehlerfall in einem inkonsistenten zustand verbleiben würde.
klassisches beispiel:
kunde A überweist zu kunde B 1000 euro.
von konto A werden 1000 euro abgebucht.
bevor auf konto B 1000 ankommen, passiert ein fehler.
ohne transaktion hast du als bank plötzlich 1000 euro zu wenig.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
MartinR
 2005-10-10 15:20
#33677 #33677
User since
2004-06-17
305 Artikel
BenutzerIn
[default_avatar]
[quote=pq,10.10.2005, 12:20]eine transaktion ist auf jeden fall dann angebracht, wenn ohne sie die datenbank im fehlerfall in einem inkonsistenten zustand verbleiben würde.[/quote]
Hallo pq,

das ist in meinem Fall aber (glaube ich) nicht der Fall. Ich hatte bisher aus einer Spalte einer Tabelle den höchsten Wert ausgelesen, um 1 erhöht und für weitere Zwecke verwendet und bei den dann neuen Datensätzen abgespeichert.

Da es mir nun passiert ist, dass zwei User "zeitgleich" auf das Skript zugegriffen hatten, hatten diese anscheinden die gleiche Zahl erhalten.

Nun habe ich diese Zahl in eine eigene Tabelle ausgelagert in der ich dann diesen Wert abspeichere. Den Vorgang des select und update + 1 wollte ich nun innerhalb eines Lock erledigen.
Gast Gast
 2005-10-10 15:49
#33678 #33678
Warum verwendest du keine Sequenzen bzw. auto_increment?
MartinR
 2005-10-10 16:17
#33679 #33679
User since
2004-06-17
305 Artikel
BenutzerIn
[default_avatar]
[quote=phaylon,10.10.2005, 13:49]Warum verwendest du keine Sequenzen bzw. auto_increment?[/quote]
Hi,

Sequenzen musst Du mir erklären.

auto_increment verwende ich zur eindeutigen Indentifikation eines Datensatzes. Da aber mehrere Datensätze funktional zusammengehören, lege ich in einer Spalte diese ID ab. Dies kann dann auch bei mehreren Datensätzen die selbe sein. ID und ID2 haben aber nichts miteinander zu tun.

Also so:
Code: (dl )
1
2
3
4
5
ID | ID2
1  | 1
2  | 2
3  | 2
4  | 3
Gast Gast
 2005-10-10 17:20
#33680 #33680
Wozu ID2?
vayu
 2005-10-10 18:15
#33681 #33681
User since
2005-01-13
782 Artikel
BenutzerIn
[default_avatar]
Quote
Da aber mehrere Datensätze funktional zusammengehören, lege ich in einer Spalte diese ID ab.


ich schätze dazu :)

also 3 hängt von 2 ab, 4 hängt von 3 ab ... etc, so versteh ich ihn.


PS: MySQL kann meines Wissens keine Transaktionen\n\n

<!--EDIT|vayu|1128954181-->
<< |< 1 2 3 >| >> 22 Einträge, 3 Seiten



View all threads created 2005-10-07 12:45.