Mein fehlendes Verständnis bei Transaktionen
Mein fehlendes Verständnis bei Transaktionen
am 31.01.2006 11:29:21 von Andreas Horn
Hallo allerseits,
wenn ich folgende SQL-Anfragen an MySQL sende:
(01) SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
(02) BEGIN;
(03) SELECT * FROM my_table WHERE id=$x;
(04) ...
(05) Auswertung und Flag setzen
(06) ...
(07) UPDATE my_table SET field1=$x1, field2=$x2, ... WHERE id=$x;
(08) ...
(09) je nach gesetztem Flag:
(10) COMMIT || ROLLBACK;
habe ich das so verstanden, daß jetzt die
Sperrung des Datensatzes mit id=$x beim SELECT in Zeile (03) erfolgt
und nicht erst beim UPDATE in Zeile (07)
oder gar erst beim COMMIT in Zeile (10)
oder habe ich was falsch in
14.2.11.3. InnoDB and TRANSACTION ISOLATION
interpretiert?
Danke schon mal für die Hilfe
Andreas
(ich hoffe ich kriege nicht schon wieder einen Rüffel
wegen persönlicher Dummheit)
Re: Mein fehlendes Verständnis bei Transaktionen
am 31.01.2006 11:46:28 von Christian Kirsch
Andreas Horn schrieb:
> Hallo allerseits,
>
> wenn ich folgende SQL-Anfragen an MySQL sende:
> (01) SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
> (02) BEGIN;
> (03) SELECT * FROM my_table WHERE id=$x;
> (04) ...
> (05) Auswertung und Flag setzen
> (06) ...
> (07) UPDATE my_table SET field1=$x1, field2=$x2, ... WHERE id=$x;
> (08) ...
> (09) je nach gesetztem Flag:
> (10) COMMIT || ROLLBACK;
>
> habe ich das so verstanden, daß jetzt die
> Sperrung des Datensatzes mit id=$x beim SELECT in Zeile (03) erfolgt
Was meinst Du denn mit 'Sperrung des Datensatzes'?
Re: Mein fehlendes Verständnis bei Transaktionen
am 31.01.2006 11:52:30 von Andreas Horn
Christian Kirsch schrieb:
> Andreas Horn schrieb:
>> Hallo allerseits,
>>
>> wenn ich folgende SQL-Anfragen an MySQL sende:
>> (01) SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
>> (02) BEGIN;
>> (03) SELECT * FROM my_table WHERE id=$x;
>> (04) ...
>> (05) Auswertung und Flag setzen
>> (06) ...
>> (07) UPDATE my_table SET field1=$x1, field2=$x2, ... WHERE id=$x;
>> (08) ...
>> (09) je nach gesetztem Flag:
>> (10) COMMIT || ROLLBACK;
>>
>> habe ich das so verstanden, daß jetzt die
>> Sperrung des Datensatzes mit id=$x beim SELECT in Zeile (03) erfolgt
>
> Was meinst Du denn mit 'Sperrung des Datensatzes'?
>
Lese- und Schreibsperre für alle Anderen
(hab's doch gewusst, irgend ein Lapsus passiert mir wieder)
Re: Mein fehlendes Verständnis bei Transaktionen
am 31.01.2006 11:56:26 von Andreas Horn
Christian Kirsch schrieb:
> Andreas Horn schrieb:
>> Hallo allerseits,
>>
>> wenn ich folgende SQL-Anfragen an MySQL sende:
>> (01) SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
>> (02) BEGIN;
>> (03) SELECT * FROM my_table WHERE id=$x;
>> (04) ...
>> (05) Auswertung und Flag setzen
>> (06) ...
>> (07) UPDATE my_table SET field1=$x1, field2=$x2, ... WHERE id=$x;
>> (08) ...
>> (09) je nach gesetztem Flag:
>> (10) COMMIT || ROLLBACK;
>>
>> habe ich das so verstanden, daß jetzt die
>> Sperrung des Datensatzes mit id=$x beim SELECT in Zeile (03) erfolgt
>
> Was meinst Du denn mit 'Sperrung des Datensatzes'?
>
Lese- und Schreibsperre für alle Anderen,
wobei Schreibsperre eigentlich bereits ausreichen würde.
(hab's doch gewusst, irgend ein Lapsus passiert mir wieder)
Re: Mein fehlendes Verständnis bei Transaktionen
am 31.01.2006 12:23:14 von Axel Schwenke
Andreas Horn wrote:
>
> wenn ich folgende SQL-Anfragen an MySQL sende:
> (01) SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
> (02) BEGIN;
> (03) SELECT * FROM my_table WHERE id=$x;
> (04) ...
> (05) Auswertung und Flag setzen
> (06) ...
> (07) UPDATE my_table SET field1=$x1, field2=$x2, ... WHERE id=$x;
> (08) ...
> (09) je nach gesetztem Flag:
> (10) COMMIT || ROLLBACK;
>
> habe ich das so verstanden, daß jetzt die
> Sperrung des Datensatzes mit id=$x beim SELECT in Zeile (03) erfolgt
Es wird ein LOCK IN SHARE MODE gesetzt. Siehe:
http://dev.mysql.com/doc/refman/4.1/en/innodb-locking-reads. html
Ob du ein SHARED LOCK oder ein exklusives Lock FOR UPDATE brauchst,
mußt du selber wissen.
> und nicht erst beim UPDATE in Zeile (07)
> oder gar erst beim COMMIT in Zeile (10)
Das Lock wird in Schritt (03) gesetzt und in (10) wieder entfernt.
Was ich aber nicht verstehe: wenn du schon in (05) weißt, ob du
COMMITen oder ROLLBACKen wirst, warum machst du dann im zweiten
Fall überhaupt erst das UPDATE (07)?
XL
Re: Mein fehlendes Verständnis bei Transaktionen
am 31.01.2006 12:49:51 von Andreas Horn
Hallo Axel,
zuerst mal 'ne Antwort warum ich ein UPDATE mache, wenn ich weiss,
dass es unnütz ist. Ich mache nicht alles selber sondern ein
Codegenerator erstellt mir die Formulare und ich fülle nur noch die
Ereignistrigger - und da lasse ich das UPDATE einfachheitshalber
einfach drin.
das mit
http://dev.mysql.com/doc/refman/4.1/en/innodb-locking-reads. html
muss ich erst mal lesen (und hoffentlich verstehen) ...
Danke für Deine Antwort
Andreas
Re: Mein fehlendes Verständnis bei Transaktionen
am 31.01.2006 14:46:13 von Andreas Horn
habe meine Zeile (03) geändert in
(03) SELECT * FROM my_table WHERE id=$x [FOR UPDATE | LOCK IN SHARE MODE];
Welche dieser 2 Varianten es dann sein wird werde ich später sehen.
Vielen Dank
Andreas
(mein Verständnis für SQL wächst endlich)
--
alles was man kann ist einfach ...
Re: Mein fehlendes Verständnis bei Transaktionen
am 31.01.2006 16:33:30 von Kai Ruhnau
Andreas Horn wrote:
> habe meine Zeile (03) geändert in
>
> (03) SELECT * FROM my_table WHERE id=$x [FOR UPDATE | LOCK IN SHARE MODE];
>
> Welche dieser 2 Varianten es dann sein wird werde ich später sehen.
Wenn du die Datensätze wie beschrieben komplett sperren möchtest, dann
brauchst du FOR UPDATE - benutze ich bei mir recht häufig.
Eine Warnung ist allerdings noch angebracht; Ich bin schon unangenehm
darüber gestolpert:
Rowlevellocking bei InnoDB ist Indexbasiert, das heißt die Bedingung
anhand derer du sperren möchtest, muss indiziert sein (Aber das scheint
bei einem Feld namens `id` gegeben zu sein).
Ansonsten, warum UPDATE wenn schon klar ist, dass ohnehin ein ROLLBACK
stattfinden wird:
Ich habe an vielen Stellen in der Software Fälle, in denen es deutlich
einfacher und übersichtlicher ist, einfach alles - wirklich alles - zu
erledigen, was an Abarbeitung anfällt, währenddessen die ganze Zeit jede
Einzeloperation zu überprüfen und erst am Ende das ROLLBACK zu machen,
auch wenn ich nach dem ersten Schleifendurchlauf schon weiß, dass das
nichts mehr wird.
Ein ROLLBACK tritt dann doch zu selten auf, um sagen zu können, dass der
Overhead dafür wirklich auffällt.
Grüße
Kai