# Deadlock/Lock Problem



## Mike90 (29. Mrz 2012)

Hallo,

wir haben ein Problem mit Deadlocks auf unserer MySQL 5.5 Datenbank.

Ausgangssituation:
Problem war, dass wenn mehrere Anwendungen auf die Datenbank editierend (UPDATE, INSERT) zugegriffen haben, dies gleichzeitig passierte und es zu DEADLOCKS kam. Daraufhin haben wir gedacht, dass wir LOCK-Statements implementieren und dadurch alles besser wird. Pustekuchen!
Gefühlt wurde es schlimmer.
Das LOCKEN von Tabellen sollte eigtl. auch nur eine vorrübergehende Lösung sein.

Nun haben wir aber das Problem, dass wenn Select-Statements zwischen das LOCKen von Tabellen kommt, diese beiden Threads sich gegenseitig sperren.

Beispiel:
Thread1:
Select * From tabelle1 where id=54785;
// sagen wir, die Abfrage dauert ca. 1min und wurde um 12:45:00 angestoßen

dann kommt ein 2ter Thread:
Thread2:
Lock Table tabelle1 WRITE;
update tabelle1 set sum=15 where id=5;
UNLOCK TABLES;
// sagen wir diese Transaktion wird um 14:45:10 angestoßen

Wenn genau dieser Fall eintrifft, dann Sperren sich die beiden Threads gegeneinander und es kommt nie zu einem Ergebnis!

Hat jemand vielleicht eine Ahnung wie man dieser Problematik aus dem Weg gehen kann ?

Beste Grüße,
Mike


----------



## Lumaraf (29. Mrz 2012)

Was für einen Tabellentyp verwendest du? Ich tippe mal auf MyISAM, da hat man häufig Probleme mit SELECTs die Änderungen an der Tabelle blockieren.


----------



## jwiesmann (29. Mrz 2012)

Was du beschreibst ist auch eigentlich so gewollt.
Da das Select wahrscheinlich auch die Tabelle sperrt.

Was helfen könnte wäre sowas:

```
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
Select * From tabelle1 where id=54785;
```

Dann wird dein Select nicht geblockt bzw. dein Select blockt dann nix.
Sollte es grundsätzlich so sein, kann man es auch global setzen.


```
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
```

btw. wenn dein Statement so lange braucht .. versuchs mal mit limit  / create index ...


----------



## ice-breaker (1. Apr 2012)

Mike90 hat gesagt.:


> Wenn genau dieser Fall eintrifft, dann Sperren sich die beiden Threads gegeneinander und es kommt nie zu einem Ergebnis!


mit deinem vereinfachten Beispiel ist dieses Verhalten nicht möglich.
Denn Thread1 hält einen Lese-Lock auf tabelle1 deswegen muss der Write-Lock von Thread2 warten, wenn Thread1 fertig ist, erst dann bekommt Thread2 den Lock zugeteilt.
Deine Vermutung der Problemursache ist also falsch 
Ihr solltest also ggf. nochmal das Grundproblem der Datenbank untersuchen und dieses beheben. Transaktionen mit InnoDB würden z.B. das Problem, dass sich Reads und Writes gegenseitig blockieren komplett aufheben, dann können nur noch Writes auf die gleichen Daten konkurrieren.



Mike90 hat gesagt.:


> Hat jemand vielleicht eine Ahnung wie man dieser Problematik aus dem Weg gehen kann ?


gar kein manuelles Locking nutzen? 
Und den Query von Thread1 eventuell soweit vereinfachen oder optimieren, dass es er schneller läuft oder den Query auf mehrere kleinere Querys aufteilen.
Wenn alle Querys nur ganz kurz arbeiten, hat man keine langen Locks im System und solche Probleme treten einfach nicht auf.


----------



## Gast2 (2. Apr 2012)

Mike90 hat gesagt.:


> Beispiel:
> Thread1:
> Select * From tabelle1 where id=54785;
> // sagen wir, die Abfrage dauert ca. 1min und wurde um 12:45:00 angestoßen
> ...



InnoDB mit SELECT ... FOR UPDATE?


----------

