Toon posts:

COMMIT/ROLLBACK in MySQL

Pagina: 1
Acties:
  • 115 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Volgens het boekje (de manual) zou MySQL tegenwoordig transactions moeten supporten bij bepaalde table types, bijvoorbeeld BDB.
Als de tabel het niet support zou je een error moeten krijgen. Nu probeer ik dit:

SET AUTOCOMMIT=0;
BEGIN;
UPDATE tablenaam SET foo='bar' where fooid=3;
...
... (meer queries)
...
COMMIT;

Dit werkt gewoon.

Nu probeer ik daarna "ROLLBACK;".

Er komt geen error, phpMySQLAdmin beweert dat de query succesvol is uitgevoerd maar de actie is dus NIET teruggedraaid.

Doe ik iets verkeerd of werkt dit gewoon niet?
Nogmaals, volgens het manual zou het ofwel moeten werken, ofwel een error moeten geven maar zeker niet NIKS.

Any ideas?

  • tomato
  • Registratie: November 1999
  • Niet online
Probeer het eens vanaf de prompt ipv met phpMyAdmin.

Verwijderd

Topicstarter
Op donderdag 01 november 2001 13:39 schreef tomato het volgende:
Probeer het eens vanaf de prompt ipv met phpMyAdmin.
Ok dat werkt iets beter maar hij kan maar 1 query rollbacken. Het lijkt alsof dat BEGIN; en COMMIT; geen reet doet. Je kunt een query geven, rollback doen en dan is die ene query undone. Met meerdere werkt het niet.

Of doe ik alsnog iets verkeerd?

  • tomato
  • Registratie: November 1999
  • Niet online
Op donderdag 01 november 2001 13:49 schreef TheMarco het volgende:
Ok dat werkt iets beter maar hij kan maar 1 query rollbacken. Het lijkt alsof dat BEGIN; en COMMIT; geen reet doet. Je kunt een query geven, rollback doen en dan is die ene query undone. Met meerdere werkt het niet.
Ik weet niet of MySQL dat kan, voor transactions heb ik MySQL nog nooit gebruikt. Is dit niet in de docs terug te vinden? Vast wel ;)

Verwijderd

Topicstarter
Dit staat in het manual:

Doe ik iets fout of werkt die meuk gewoon niet?
By default, MySQL runs in autocommit mode. This means that as soon as you execute an update, MySQL will store the update on disk.

If you are using transactions safe tables (like BDB, InnoDB or GEMINI), you can put MySQL into non-autocommit mode with the following command:

SET AUTOCOMMIT=0

After this you must use COMMIT to store your changes to disk or ROLLBACK if you want to ignore the changes you have made since the beginning of your transaction.

If you want to switch from AUTOCOMMIT mode for one series of statements, you can use the BEGIN or BEGIN WORK statement:

BEGIN;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summmary=@A WHERE type=1;
COMMIT;

Note that if you are using non-transaction-safe tables, the changes will be stored at once, independent of the status of the autocommit mode.

If you do a ROLLBACK when you have updated a non-transactional table you will get an error (ER_WARNING_NOT_COMPLETE_ROLLBACK) as a warning. All transactional safe tables will be restored but any non-transactional table will not change.

  • tomato
  • Registratie: November 1999
  • Niet online
Op donderdag 01 november 2001 14:03 schreef TheMarco het volgende:
Dit staat in het manual:
Zou dus gewoon moeten werken.
Doe ik iets fout of werkt die meuk gewoon niet?
Geef eens een voorbeeld van je statements.

Verwijderd

Topicstarter
Ok voorbeeldje met een test dbtje met 1 table:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| users     |
+----------------+
1 row in set (0.00 sec)

mysql> show columns from users;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type      | Null | Key | Default | Extra        |
+---------+-------------+------+-----+---------+----------------+
| useid   | int(11)     |   | PRI | NULL    | auto_increment |
| usename | varchar(50) |   |     |    |            |
| usenick | varchar(20) |   |     |    |            |
| usesex  | char(1)     |   |     |    |            |
+---------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

Dit ter illustratie.

Ik doe dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
mysql> select * from users;
+-------+---------+----------+--------+
| useid | usename | usenick  | usesex |
+-------+---------+----------+--------+
|     1 | Anton   | Whatever | M    |
|     2 | Marco   |     |     |
|     3 | Piet    |     |     |
|     4 | eikel3  |     |     |
+-------+---------+----------+--------+
4 rows in set (0.01 sec)

mysql> SET AUTOCOMMIT=0;
Query OK, 0 rows affected (0.00 sec)

mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> UPDATE users SET usename='Frits' WHERE usename='eikel3';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> UPDATE users SET usename='Klaas' WHERE usename='Piet';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> COMMIT;
Query OK, 0 rows affected (0.01 sec)

mysql> select * FROM users;
+-------+---------+----------+--------+
| useid | usename | usenick  | usesex |
+-------+---------+----------+--------+
|     1 | Anton   | Whatever | M    |
|     2 | Marco   |     |     |
|     3 | Klaas   |     |     |
|     4 | Frits   |     |     |
+-------+---------+----------+--------+
4 rows in set (0.00 sec)

mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)

mysql> select * FROM users;
+-------+---------+----------+--------+
| useid | usename | usenick  | usesex |
+-------+---------+----------+--------+
|     1 | Anton   | Whatever | M    |
|     2 | Marco   |     |     |
|     3 | Klaas   |     |     |
|     4 | Frits   |     |     |
+-------+---------+----------+--------+
4 rows in set (0.00 sec)

Nu is er zelfs NIKS rolled back;

Als ik 1 query doe en dan rollback dan wordt die wel ongedaan gemaakt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
mysql> SET AUTOCOMMIT=0;
Query OK, 0 rows affected (0.01 sec)

mysql> UPDATE users SET usename='Frits' WHERE usename='JOOP';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM users;
+-------+---------+----------+--------+
| useid | usename | usenick  | usesex |
+-------+---------+----------+--------+
|     1 | Anton   | Whatever | M    |
|     2 | Marco   |     |     |
|     3 | Klaas   |     |     |
|     4 | Frits   |     |     |
+-------+---------+----------+--------+
4 rows in set (0.00 sec)

mysql> ROLLBACK;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM users;
+-------+---------+----------+--------+
| useid | usename | usenick  | usesex |
+-------+---------+----------+--------+
|     1 | Anton   | Whatever | M    |
|     2 | Marco   |     |     |
|     3 | Klaas   |     |     |
|     4 | JOOP    |     |     |
+-------+---------+----------+--------+
4 rows in set (0.00 sec)

Nu met twee:

mysql> SELECT * from users;
+-------+---------+----------+--------+
| useid | usename | usenick  | usesex |
+-------+---------+----------+--------+
|     1 | Anton   | Whatever | M    |
|     2 | Marco   |     |     |
|     3 | Klaas   |     |     |
|     4 | JOOP    |     |     |
+-------+---------+----------+--------+
4 rows in set (0.00 sec)

mysql> SET AUTOCOMMIT=0;
Query OK, 0 rows affected (0.01 sec)

mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> UPDATE users SET usename='Hein' WHERE usename='JOOP';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> UPDATE users SET usename='Johan' WHERE usename='Marco';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)

mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * from users;
+-------+---------+----------+--------+
| useid | usename | usenick  | usesex |
+-------+---------+----------+--------+
|     1 | Anton   | Whatever | M    |
|     2 | Johan   |     |     |
|     3 | Klaas   |     |     |
|     4 | Hein    |     |     |
+-------+---------+----------+--------+
4 rows in set (0.01 sec)

En we zien dat er maar 1 query ongedaan gemaakt is en GEEN twee!!!

  • tomato
  • Registratie: November 1999
  • Niet online
TheMarco: Ok voorbeeldje met een test dbtje met 1 table:
Zet het even tussen [ code] en [/ code], dan is het wat leesbaarder ;)

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:46

Creepy

Tactical Espionage Splatterer

After this you must use COMMIT to store your changes to disk or ROLLBACK if you want to ignore the changes you have made since the beginning of your transaction.

Snappie?? Nee? ff vertaald in het NL dan..

Na dit moet je COMMIT gebruiken om je gegevens naar disk te schrijven OF ROLLBACK gebruiken om de veranderingen te negeren sinds het begin van de transactie

ROLLBACK geven NA een COMMIT heeft dus geen nut.. want na COMMIT heb je alle veranderingen al doorgevoerd.. IN PLAATS VAN COMMIT moet je ROLLBACK gebruiken.. NIET na elkaar..

COMMIT voert gewoon alle veranderingen in 1 keer door i.p.v. dat alle losse queries los van elkaar worden uitgevoerd.. Na een commit is het (in het geval van MYSQL) niet meer mogelijk een ROLLBACK te geven.

edit:
Hmmm..... niet helemaal dus zoals ik hiero zeg.. na je commit wordt er met rollback toch 1 query "hersteld".. vaaaaaaag

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • tomato
  • Registratie: November 1999
  • Niet online
Op donderdag 01 november 2001 14:29 schreef Creepy het volgende:
Na dit moet je COMMIT gebruiken om je gegevens naar disk te schrijven OF ROLLBACK gebruiken om de veranderingen te negeren sinds het begin van de transactie
Iemand die wakker is :)

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:46

Creepy

Tactical Espionage Splatterer

Op donderdag 01 november 2001 14:32 schreef tomato het volgende:

[..]

Iemand die wakker is :)
Humz.. een beetje dan :-)

Wel vaag dat ze BEGIN..COMMIT alleen gebruiken voor transacties (en vandaar dat na een commit een rollback ook niks zou moeten doen) en niet meteen een muli-level rollback hebben ingebouwd (ik meen me te herinneren dat Oracle dit wel heeft).

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • tomato
  • Registratie: November 1999
  • Niet online
Op donderdag 01 november 2001 14:41 schreef Creepy het volgende:
Wel vaag dat ze BEGIN..COMMIT alleen gebruiken voor transacties (en vandaar dat na een commit een rollback ook niks zou moeten doen) en niet meteen een muli-level rollback hebben ingebouwd (ik meen me te herinneren dat Oracle dit wel heeft).
Vaag dat MySQL iets niet heeft dat Oracle wel heeft? :D

Er is zoveel vaag :z ;)

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:46

Creepy

Tactical Espionage Splatterer

MySQL heeft (helaas) wel meer niet dat Oracle wel heeft (iets doms zoals sub queries ofzo.. net alsof niemand die gebruikt :) )

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
Op donderdag 01 november 2001 14:29 schreef Creepy het volgende:
Na dit moet je COMMIT gebruiken om je gegevens naar disk te schrijven OF ROLLBACK gebruiken om de veranderingen te negeren sinds het begin van de transactie
Mijn held! Bedankt!!!!

Nu blijft er voor mij nog 1 vraag openstaan:

Wat is de geldigheid van "SET AUTOCOMMIT=0;" ?

Blijft dat dan voor goed zo of alleen voor deze SQL sessie?
Ik vraag dit omdat je bij enkele queries natuurlijk niet dat hele mechanisme van begin, doe iets, commit/rollback wilt hoeven gebruiken.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:46

Creepy

Tactical Espionage Splatterer

hmm.. in ieder geval de sessie..

als je BEGIN doet wordt tot en met de COMMIT of ROLLBACK die var automatisch op 0 gezet.. daarna wordt ie weer teruggezet op de oorspronkelijke waarde... dus ff voor 1 query gebruik maken van BEGIN..COMMIT dan hoef je die var niet te gebruiken..

Ik denk niet dat dat voor altijd geld..anders zou de DBA niet zo blij zijn denk ik :)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Topicstarter
Op donderdag 01 november 2001 15:13 schreef Creepy het volgende:
hmm.. in ieder geval de sessie..
Hmm ik heb het al opgelost door in mijn DB class een method starttransaction, commit, rollback en aborttransaction te maken.

starttransaction zet hem op 0 en doet een BEGIN;.
commit en rollback doen zoals ze heten en zetten hem weer op 1 en aborttransaction zet hem ook op 1 (voor als de allereerste query direct mislukt)

Lijkt me wel okee zo :)

Iedereen bedankt. Ik heb weer wat geleerd vandaag!
Pagina: 1