# Threadsicherheit von MySQL-Verbindungen



## Freddy (12. Aug 2003)

Kennt sich hier jemand mit der genaueren Beschaffenheit von Verbindungen des MySQL Connector/J 2.0 aus?
Ich arbeite an einem Chatserver, dessen Benutzerverwaltung mit MySQL realisiert ist. Nun kann es ja passieren, dass sich zwei Benutzer gleichzeitig einloggen ---> Thread A holt sich ein Statement von der Verbindung, schickt ein Query ab, während Thread B dies fast gleichzeitig auch macht. Ich kann dieses Szenario nicht erzwingen, um die Auswirkungen (z.B. eine Exception in Thread A oder beschädigtes ResultSet) herauszufinden, und deswegen frage ich mich: Wie muss ich eine Verbindung synchronisieren, um sie Thread-sicher zu machen?

a) garnicht;
b)

```
ResultSet res;
synchronized (connection) {
res = connection.createStatement().executeQuery("SELECT * FROM table");
while(res.next()) {
// Daten verarbeiten
}
}
```
_oder_
c)

```
ResultSet res;
synchronized (connection) {
res = connection.createStatement().executeQuery("SELECT * FROM table");
}
while(res.next()) {
// Daten verarbeiten
}
```

Noch einmal zur Verdeutlichung: In Beispiel b) ist die Verarbeitung des ResultSet in den synchronisierten Block mit einbezogen, bei c) steht sie außerhalb.


----------



## bummerland (12. Aug 2003)

meiner meinung nach braucht die funktion, in der der sql-befehl ausgeführt wird, das keyword synchronized. damit wird sichergestellt, dass die funktion zu ende ausgeführt wird, bevor eine andere dran kommt. (bin mir aber nicht 100% sicher)


----------



## Freddy (12. Aug 2003)

Ob executeQuery() synchronisiert ist oder sein muss, weiß ich ja eben nicht. Aber selbst wenn dies der Fall ist, kann ja ein anderer Thread mit einem Query auf der gleichen Verbindung meinem ResultSet in die Quere kommen.


----------



## bummerland (13. Aug 2003)

ich denke mal, dagegen beugt mysql selbst auch vor, indem immer nur 1 befehl gleichzeitig ausgeführt werden kann, oder?


----------



## Freddy (13. Aug 2003)

Wenn ich gleichzeitig mit mehreren Threads in eine Verbindung schreibe, dann krieg ich entweder ne Exception oder es kommt Datenmüll an. Und ich frage ja nun gerade, ob da ein Schutz ist.


----------



## omosde (13. Aug 2003)

Wenn es dir als Frage nur darum geht, ob es sicher ist, wenn 2 oder mehr Anfragen (theoretisch) gleichzeitig bei der Datanbank eintreffen, dann sollte eine synchronisation der Threads nicht notwendig sein! Solange setAutoCommit() fuer die connection gilt, sollte diese Sicherheit auf jeden Fall die DB uebernehmen! Sie fuehrt die Anfragen dann nacheinander oder quasiparallel!

Wenn du dir nicht sicher bist, dann schreib dir doch nen kleines Proggi, was auf einer Verbindung ueber mehrere Threads nichts anderes tut, als den DB-Server mit Anfragen zu bombadieren! 

MfG
omosde


----------



## Freddy (13. Aug 2003)

Ich habe mir jetzt solch ein kleines "DoS"-Programm programmiert, welches mit 100 Threads gleichzeitig auf einer Verbindung soviele SELECT-Anfragen wie möglich ausführt. In einer Minute wurden bis zu *11709* Queries gesendet und deren ResultSets über System.out ausgegeben. Erstaunlicherweise tauchte nicht eine Exception auf, obwohl ich diesen Test mehrmals gemacht habe.

Also: Problem gelöst. Danke


----------



## DTR (22. Aug 2003)

Hi,
ich weiß ja nicht, wann du deine Abfragen absetzt, oder wie dein Programm sonst organisiert ist. Vieleicht geht das bei dir ja auch Problemlos. Aber grundsätzlich würde ich nicht eine Connection öffnen und während der gesamten Verarbeitung offen lassen, sonder am Anfang einer Methode eine Connection öffnen und am Ende Wieder schließen. Das hat einerseits den Vorteil, das du für jeden Thread eine eigene Connection hast, andererseids kommt es so nicht zu einem Unerwarteten Timeout der Connection, was meiner Meinung nach der Hauptvorteil der Geschichte ist.


----------



## Freddy (31. Aug 2003)

Bei MySQL tritt dieser Timeout erst nach 8 Stunden ein, und mit dem Property _autoReconnect_ lässt sich auch dieses Problem lösen.
Jeder Verbindungsaufbau braucht unnötig (Rechen-)Zeit und CPU, die man sparen kann, indem man eine persistente Verbindung benutzt. Ich sehe da nur Vorteile gegenüber temporären Verbindungen.


----------

