# Was passiert bei absolut zeitgleichem Zugriff auf eine Tablerow



## dmike (3. Aug 2011)

Mit den MultiCore Rechnern ist es ja möglich, dass bei zwei Threads einer VM jeder einzelne Thread auf einem eigenen Core läuft und absolut zeitgleich mit dem anderen ein und die selbe Zeile einer Tabelle liest oder schreibt. 

Sagen wir ich benutze Optimistic Locking.

Beispiel: Shopsystem

Angenommen: Nur noch 5 Stück von Produkt A

Zwei Threads greifen kurz nacheinander auf das Produkt zu und lesen beide: Noch 5 Stück verfügbar
Jeder Thread kauft 5 Stück ein und möchte die Verüfbarkeit entsprechend aktualisieren. Das passiert rein zufällig zur selben Zeit.

Frage:
a) Was passiert jetzt? Wird ein Exception geworfen? Welcher Thread "gewinnt"?

b) Was muss die Datenbank können um die Situation zu handeln?

c) Macht es einen Unterschied für das Verhalten, ob man für den Zugriff auf die Datenbank Hibernate oder ähnliches verwendet?


----------



## Evil-Devil (3. Aug 2011)

Ich würde sagen, egal.
Behandel den Fall in der Logik der Anwendung. Nachbestellen musst so oder so. Falls keine Nachbestellung mehr möglich ist, kannst du immer noch die Bestellung stornieren.

Wie sich das DBMS verhält wird sehr stark vom jeweils verwendeten DBMS abhängen und kann denke ich nicht pauschal beantwortet werden.


----------



## dmike (3. Aug 2011)

Evil-Devil hat gesagt.:


> Ich würde sagen, egal.
> Behandel den Fall in der Logik der Anwendung. Nachbestellen musst so oder so. Falls keine Nachbestellung mehr möglich ist, kannst du immer noch die Bestellung stornieren.



Naja mir geht es um's Prinzipielle. Das Shop-Beispiel war ja nur ein Beispiel. Nimm z.B. eine Veranstaltung mit 10 freien Plätzen. Mit Nachbestellen iss da nix. Jetzt kommen zwei Threads an, der eine bucht 7 Plätze der andere 4, macht 11. Das passiert zeitgleich. 

Wenn jetzt eine Exception auf unterster JDBC-Ebene geworfen würde, dann könnte ich damit leben.

Mit App-Logik das wird kompliziert. Dann bräuchte ich wohl ein Singleton, dass letztlich den Zugriff auf alle Threads bekommt und synchronisert also letztlich parallele Threads serialisiert. Was ja eigentlich nicht so gut ist.   Oder?





Evil-Devil hat gesagt.:


> Wie sich das DBMS verhält wird sehr stark vom jeweils verwendeten DBMS abhängen und kann denke ich nicht pauschal beantwortet werden.


Ein paar Standard-Strategien wie das die üblichen Verdächtigen machen müsste es schon geben, sag ich mal.


----------



## Gast2 (3. Aug 2011)

Schau dir an wie es Airlines machen. Wenn du auf einem Portal nach Flügen suchst werden dir jede Menge freier Plätze angezeigt. Wenn du dann buchst wird versucht dir die Anzahl Plätze fest zu reservieren. Sollte in der Zischenzeit jemand Plätze reserviert haben bekommst du die Nachricht das deine Reservierung nicht mehr abgeshclossen werden kann das sich in der Zwischenzeit etwas geändert hat.


Das zwei Threads zum *genau* gleichen Zeitpunkt eine Anfrage starten ist sehr unwahrscheinlich, das der Datenbankserver beide Anfragen zur gleichen Zeit erhält noch wesentlich unwahrscheinlicher. Aber selbst dann werden die Anfragen im Datenbankserver verwaltet und das RDMBS muss sich darum kümmern.

Es kommt halt auch drauf an wie die Anfragen gestellt werden. Ein "SELECT FOR UDPATE" verhält sich anders als ein "SELECT" oder "UPDATE". 

Stichworte: ACID und Transaktionsmanagement => Transaktion (Informatik) ? Wikipedia


----------



## ice-breaker (3. Aug 2011)

Wenn du Transaktionen nutzt hast du solche Probleme nicht mehr 
Je nach Transaktionslevel bekommst du mehr Garantien, welche Probleme nicht mehr auftreten können, unbedingt mal ansehen 

Als Tipp noch:
Folgendes ist bei sowas trotzdem immer sehr nützlich:

```
UPDATE ... SET col = col - 5 WHERE ... col >= 5
```


----------



## dmike (3. Aug 2011)

fassy hat gesagt.:


> Schau dir an wie es Airlines machen. Wenn du auf einem Portal nach Flügen suchst werden dir jede Menge freier Plätze angezeigt. Wenn du dann buchst wird versucht dir die Anzahl Plätze fest zu reservieren. Sollte in der Zischenzeit jemand Plätze reserviert haben bekommst du die Nachricht das deine Reservierung nicht mehr abgeshclossen werden kann das sich in der Zwischenzeit etwas geändert hat.
> 
> 
> Das zwei Threads zum *genau* gleichen Zeitpunkt eine Anfrage starten ist sehr unwahrscheinlich, das der Datenbankserver beide Anfragen zur gleichen Zeit erhält noch wesentlich unwahrscheinlicher. Aber selbst dann werden die Anfragen im Datenbankserver verwaltet und das RDMBS muss sich darum kümmern.
> ...



a) Airline: Das Beispiel sieht nach Optimistic locking aus
b) sehr unwahrscheinlich ist eben nicht 0. Ist nur eine Frage wie lange das System läuft irgendwann passiert's und man hat den Ärger.
c) Locken möchte ich den Datensatz nicht => optimistic lock
ing (siehe 1. Post)


----------



## dmike (3. Aug 2011)

ice-breaker hat gesagt.:


> Wenn du Transaktionen nutzt hast du solche Probleme nicht mehr
> Je nach Transaktionslevel bekommst du mehr Garantien, welche Probleme nicht mehr auftreten können, unbedingt mal ansehen


Nicht in jedem Fall. Beim optimistic locking sollte man z.B. keinen Zeitstempel zur Versionierung benutzen, weil das OS nicht genau genug auflösen kann und zwei OPerationen die tatsächlich nacheinander statt finden für den zeitmesser im OS gleichzeitig passieren, egal ob mit oder ohne Transaktion (wird so in "Java Persistence with Hibernate" empfohlen). Mich interessiert halt der Fall absolut gleichzeitig, kann dann das optimistic locking auch noch funktionieren?



ice-breaker hat gesagt.:


> Als Tipp noch:
> Folgendes ist bei sowas trotzdem immer sehr nützlich:
> 
> ```
> ...


Wenn ich das richtig verstanden habe, dann sollte es eigentlich nie zu dem Situation kommen, dass col > 5 ist.


----------



## muckelzwerg (4. Aug 2011)

Ich versteh Dein Problem noch nicht ganz. Baust Du gerade eine eigene Datenbank?
Dafür gibt es doch eben die Transaktionen. 
Letztlich wird da wieder sequentiell gearbeitet, auch auf Multicore-Systemen gibt es kein echtes "gleichzeitig das Selbe tun".
Es gibt so eine Art "virtuelle Parallelität" durch Interleaving. Das hast Du im ersten Beitrag beschrieben.
Aber genau dafür gibt es dann doch wieder Dinge wie atomare Test&Set Operationen usw.
Das spielt für Dich aber doch keine Rolle, weil Du die Kontrolle an die Datenbankfunktionen abgibst und dort die Sequentialisierung stattfindet (durch Transaktionen ...).

Was ohne Transaktionen passiert, kannst Du doch einfach mal ausprobieren. 
Bau Dir ein kleines Testprogramm mit Schleifen und Zählern oder sowas.


----------

