Theorie : Mehrer Threads - Commit (MySQL)

Status
Nicht offen für weitere Antworten.

Tallan

Bekanntes Mitglied
Hallo zusammen,

folgedner Fall :

in einem Programm laufen 2 Treads A und B.
A und B schreiben jeweils etwas in die Datenbank ( unterschiedliche Tabellen )
Es werden PreparedStatement erstellt und dann einen Commit ausgeführt.
Das Programm selbst hat nur eine Datenbankverbindung.

Gehe ich richtig in der Annahme das wenn Thread A einen Commit über die DB-Verbindung ausführt die Anweisungen von B auch ausgeführt werden?
Falls ja, gibt es einen weg das abzusichern ohne auf Threads zu verzichten und ohne eine 2te Datenbankverbindung zu erstellen?
 
Zuletzt bearbeitet:

MrWhite

Bekanntes Mitglied
Sowas nennt sich Race-Condition und kann vorkommen, wenn Thread1 den commit macht wenn Thread 2 den Query schon abgeschickt hat aber noch nicht comitted hat.

Ob das vorkommen kann, hängt eher vom Treiber ab. Es könnte schon sein, dass es da zu ganz anderen Problemen kommt oder das Problem schon bedacht wurde.

Am besten hat jeder Thread seine eigene Connection oder du deklarierst die Methode, die Queries ausführt als synchronized.
 

tfa

Top Contributor
tfa, mit deiner zweiten Aussage liegst du falsch. Schonmal was von synchronized gehoert?

Wie waere es mit einem threadsicheren Queue fuer Queries?

Was bekommt denn deine Datenbank von dem synchronized mit?
Wenn du auf der Connection commit aufrufst wird alles committet, egal welcher Thread welche Queries abgesetzt hat. Du kannst hier keine Transaktionen trennen.
 

MrWhite

Bekanntes Mitglied
Ich habe doch einen Weg beschrieben, das abzusichern. Ein threadsicherer Queue in den Queries gelegt werden z.B. und der irgendwann von einem Thread ausgefuehrt wird.

Gemaess der Fragestellung.
 

DamienX

Aktives Mitglied
Mal abgesehen davon dass ich noch nie jemanden bei Datenmanipulationen von
"Queries" sprechen habe hören...

1. Wenn sie auf unterschiedlichen Tabellen arbeiten ist es sowieso egal.
2. Selbst wenn die commits übereinanderlaufen wirst du auf einigermaßen
namhaften Datenbanken niemals erleben dass sich daten "vermischen" oder
sonstiges (Ich denke darauf zielte die Frage ab... wenn nicht... auch egal ;D )

-> Was allerdings passieren kann ist dass du zb einen Update machst... dieser noch nich durchgeführt
wurde und aus deiner programmlogik einen erneuten Updatebefehl abgibts!

Dann sperrt der erste die Datensätze und der Zweite wartet bis Transaktion 1 durchgelaufen ist.
Dann macht Update 2 seine arbeit.

Das kann evtl. nich gewollt sein aber liegt dann an der client Seite.
 
M

maki

Gast
Falls ja, gibt es einen weg das abzusichern ohne auf Threads zu verzichten und ohne eine 2te Datenbankverbindung zu erstellen?
Warum willst du denn mehrere DB Verbindungen verhindern?
Ist sehr normal mehrere Verbindungen in einer Multithreaded App zu haben, auch als ConnectionPool bekannt.

Wenn du gutes Transaktionens- Management und -Deklaration willst solltest du dir Spring oder EJB ansehen.
 

Tallan

Bekanntes Mitglied
Warum willst du denn mehrere DB Verbindungen verhindern?
Ist sehr normal mehrere Verbindungen in einer Multithreaded App zu haben, auch als ConnectionPool bekannt.

Wenn du gutes Transaktionens- Management und -Deklaration willst solltest du dir Spring oder EJB ansehen.

Verhindern möchte ich es nicht unbedingt ich wollte nur nicht unbedingt für jeden anweder eine extra DB-Con aufbauen zumal der zugriff auf die Datenbank nicht direkt von client ausgeführt wird sondern über eine middelware läuft
 

tfa

Top Contributor
Verhindern möchte ich es nicht unbedingt ich wollte nur nicht unbedingt für jeden anweder eine extra DB-Con aufbauen zumal der zugriff auf die Datenbank nicht direkt von client ausgeführt wird sondern über eine middelware läuft

Gerade wenn du eine Middleware (bzw. Applicationserver) hast, brauchst du nicht so viele DB-Connections. Das kann alles der Server managen, je nachdem wie die Clientanfragen eintreffen.

Der Tipp mit dem Spring-Framework ist übrigens Gold wert. Hiermit brauchst du dich fast gar nicht mehr um Connection-Pooling und Transaktionsverwaltung kümmern. Jedenfalls ist nicht viel Handarbeit notwendig.
 
G

Gast2

Gast
Sowas nennt sich Race-Condition und kann vorkommen, wenn Thread1 den commit macht wenn Thread 2 den Query schon abgeschickt hat aber noch nicht comitted hat.
jain

Thread A - "select * from tabelle1"
Thread B - "update tabelle 2 SET ..."

das funktioniert super ohne das ich mich um etwas kümmern muss ... beide SQL-Statements sind für sich atomar ... die Datenbank hat sich hier darum zu kümmern das da nichts schief läuft ... wenn die DB das nicht macht - wegschmeißen die taugt nichts

holst Du Dir aber Daten aus der DB, machst damit eine Berechnung und dann wieder ein UPDATE mit den neuen Daten ... dann musst Du darauf achten das andere Threads nicht die Daten verhauen - Race Conditions (wurde aber schon erwähnt) ... allerdings bieten hierfür Treiber der gängige Datenbanken entsprechende Statements um auch mehrere SQL-Statements als atomar zu definieren - Transaction (wurde schon erwähnt) ... dazu mal die passenden Handbücher der Datenbanken lesen ... Du kannst aber auch auf Frameworks zugreifen die das Ganze abstrahiert haben - auf einfache Benutzung hin

Am besten hat jeder Thread seine eigene Connection
macht keinen Sinn ... hier ist es egal ob Du mehrere Connections hast oder nur eine ... Du kannst auch mit 2 Connections eine Race Condition erhalten

hand, mogel
 

Tallan

Bekanntes Mitglied
jain

Thread A - "select * from tabelle1"
Thread B - "update tabelle 2 SET ..."

das funktioniert super ohne das ich mich um etwas kümmern muss ... beide SQL-Statements sind für sich atomar ... die Datenbank hat sich hier darum zu kümmern das da nichts schief läuft ... wenn die DB das nicht macht - wegschmeißen die taugt nichts

holst Du Dir aber Daten aus der DB, machst damit eine Berechnung und dann wieder ein UPDATE mit den neuen Daten ... dann musst Du darauf achten das andere Threads nicht die Daten verhauen - Race Conditions (wurde aber schon erwähnt) ... allerdings bieten hierfür Treiber der gängige Datenbanken entsprechende Statements um auch mehrere SQL-Statements als atomar zu definieren - Transaction (wurde schon erwähnt) ... dazu mal die passenden Handbücher der Datenbanken lesen ... Du kannst aber auch auf Frameworks zugreifen die das Ganze abstrahiert haben - auf einfache Benutzung hin


macht keinen Sinn ... hier ist es egal ob Du mehrere Connections hast oder nur eine ... Du kannst auch mit 2 Connections eine Race Condition erhalten

hand, mogel

Atomare querrys sind kein Porblem.
Die Threads schreiben auch nicht auf den selben Datensätzen daher fällt die race condition auch raus.

Ein Beispiel zu dem Problem.

Thread A legt eine Zeile in mehreren Tabellen an die Aufeinander verweist hierfür setze ich wie im Tutorial beschrieben den autocommit auf false.. baue meine Statments fülle es mit Daten und commite dann.

In der Zwischenzeit will Thread B munter Atomare Operationen ausführen, sprich einzelne querrys ausführen.

Wenn ich für beide jetzt nur eine Connection hab kann folgendes passieren.

Entweder hat Thread B Autocommit an und kann somit die einzelnen Querrys raushauen, womit die Transaktion in A sinnlos ist da ja Autocommit an ist..

Oder Aber B hat autocommit aus, sendet seine Querrys, in Thread A funktioniert etwas nicht -> Rollback -> Rollback der Daten von B weil für die Querrys von B kein Commit stattfand.


Wenn ich 2 Connections nutzte hab ich kein Problem, die Frage ist allerdings ob es da eine Sinvolle alternative gibt, da es ja etwa mehr als nur 2 User sein werden.


Gedanken über einen Connection Pool und das Spring Framework werde ich mir machen, danke für die Tips
 

tfa

Top Contributor
Was haben denn Threads damit zu tun? Die DB weiß nichts von Java-Threads. Hier zählen nur die Datenbank-Sessions, und die hängen an der Connection. Autocommits und Rollbacks werden auch an der Connection gemacht, nicht an Threads...

Entweder versteh ich euch nicht, oder ihr verwechselt was. ???:L
 
M

maki

Gast
Gedanken über einen Connection Pool und das Spring Framework werde ich mir machen, danke für die Tips
Wenn du Spring nutzt, musst du dir keine (oder kaum) Gedanken mehr um solche Low-Level Probleme machen ;)

Da reicht ein [c]@Transactional[/c] um die Methoden zu markieren welche in einer Transaktion laufen soll.
 

Tallan

Bekanntes Mitglied
Was haben denn Threads damit zu tun? Die DB weiß nichts von Java-Threads. Hier zählen nur die Datenbank-Sessions, und die hängen an der Connection. Autocommits und Rollbacks werden auch an der Connection gemacht, nicht an Threads...

Entweder versteh ich euch nicht, oder ihr verwechselt was. ???:L

threads in soweit das der zeitpunkt wann der commit stattfinden nicht festgelegt ist und auch keine reihenfolge haben muss
 
G

Gast2

Gast
Thread A legt eine Zeile in mehreren Tabellen an die Aufeinander verweist hierfür setze ich wie im Tutorial beschrieben den autocommit auf false.. baue meine Statments fülle es mit Daten und commite dann.

In der Zwischenzeit will Thread B munter Atomare Operationen ausführen, sprich einzelne querrys ausführen.

[...]

ay caramba ... das dürfte wirklich an der Connection hängen

hand, mogel
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben