Avatar billede webcreator Nybegynder
07. december 2005 - 09:24 Der er 22 kommentarer og
1 løsning

Transaction Support

Hej Eksperter.

Jeg undre mig lidt over den måde MySQL håndterer System Transactions på. Lad os tage udgangspunkt i flg. eksempel :

START TRANSACTION;
INSERT INTO test.mails VALUES ('test1@microsoft.com', 'haps1@haps.dk', 'Yo - Golf on sunday?', 'Hey Bill. Golf on sunday?', now());
INSERT INTO test.mails VALUES ('test2@microsoft.com', 'haps2@haps.dk', 'Yo - Golf on sunday?', 'Hey Bill. Golf on sunday?', now());
INSERT INTO test.mails VALUES ('test3@microsoft.com', 'haps3@haps.dk', 'Yo - Golf on sunday?', 'Hey Bill. Golf on sunday?', now());
COMMIT;

Som det ses starter jeg en transaktion i starten og committer den i slutningen. Altså burde dataene ikke blive indsat i databsen, hvis jeg fx pludselig afslutter transaktionen efter det 2. INSERT-statement. Men kigger man i tabellem Mails, er både post 1 og 2 blevet indsat. Hvordan kan det være?

Jeg kan ganske fint gå tilbage til sidste konsistent tilstand vha. ROLLBACK - men det burde mig bekendt ikke være nødvendigt! Den skal slet ikke committe data før COMMIT kaldes.

Nu ved jeg i øvrigt godt at der ikke er nogen FOREIGN KEYs der gør, at databasen bliver inkonsistent. Men jeg kan ikke tro at dette er grunden til, at dataene alligevel bliver committet øjeblikkeligt.

Håber nogen af jer har en forklaringen. Enten at "Sådan fungerer MySQL altså bare.." eller "Du har jo også lavet en fejl.." :)
Avatar billede webcreator Nybegynder
07. december 2005 - 09:28 #1
Har det noget med ISOLATION LEVEL at gøre mon ?
Avatar billede webcreator Nybegynder
07. december 2005 - 09:42 #2
Det er muligvis også relevant at nævne at tabellen er af typen InnoDB
Avatar billede dragonknight Juniormester
07. december 2005 - 10:41 #3
Du har fat i noget af det rigtige, for inden der er lavet en commit, kan du fortryde med rollback. Efter commit, kan du ikke fortryde med rollback. Der er derfor "Sådan fungerer MySQL altså bare..", og vil du tilbage til det oprindelige efter 2. inseret satement, kan du kun gøre det med en rollback.

SQL transaction er ikke færdig før der er udført en commit eller en rollback, så du slutter dermed ikke transactions efter 2. insert, men stopper den bare.
Avatar billede webcreator Nybegynder
07. december 2005 - 10:50 #4
Hej Dragon.

Tak for input. Jeg synes dog det er meget mærkeligt. Ifl. MySQLs egen manual skulle AutoCommit blive deaktiveret når man starter en transaktion - og det bliver den helt klart ikke i mit eksempel, eftersom dataene indsættes i min tabel inden Commit-kaldet.

Hvad angår Rollback, så kunne man jo forestille sig et program som går ned midt i en transaktion (strømmen går til computeren) - så vil rollback ikke blive kaldt, og databasen kommer dermed i en inkonsistent tilstand.
Avatar billede dragonknight Juniormester
07. december 2005 - 11:07 #5
Det har du ret i, at Autocommit er deaktiveret når du starter en transaction, men din transaction er ikke færdigudført før der kommer en commit eller en rollback. Ændringer inden commit bliver først permanente når commit er udført, og har du locks på, så bliver de også først released ved commit.
Når du stopper efter 2. insert, så er ændringerne i DB ikke permanente. Da der ikke er kommet en commit, så kan du kun afslutte transaction ved rollback. Nu er ændringerne peremanente, men også i sin oprindelig form.

In short, den eneste måde du kan afslutte en transaction på er ved commit eller rollback.

An active transaction exists only after an SQL START QUERY statement is executed subsequent to executing the SQL START TRANSACTION statement for the same connection as the query.  An active transaction must be ended with either an SQL COMMIT TRANSACTION or SQL ROLLBACK TRANSACTION statement before attempting to disconnect from the data source with an SQL DISCONNECT DATASOURCE statement.  Otherwise, the disconnect attempt will fail because of the active transaction.


Går strømmen midt i en transaction, bliver den ikke afsluttet, men blot stoppet.

http://www.liant.com/iSQL/help/InstantSQLAdvancedStatements.htm
Avatar billede dragonknight Juniormester
07. december 2005 - 11:11 #6
Avatar billede webcreator Nybegynder
07. december 2005 - 11:32 #7
Ok. Er jeg gal på den når jeg siger, at det er ualmindelig uhensigtsmæssigt at MySQL har lavet det sådan? Det kan vel netop, som jeg også beskrev før, give en inkonsistent database ved strøm-afbrydelse midt i en transaktion (?).
Avatar billede webcreator Nybegynder
07. december 2005 - 11:40 #8
Min kære lærer har lige vist mig et eksempel i .NET der gør brug af en indbygget Transaction Klasse. Her indsættes dataene _ikke_ i databasen hvis ikke COMMIT kaldes. Så her ser det ud til at virke som forventet.
Avatar billede webcreator Nybegynder
07. december 2005 - 11:41 #9
(Er under uddannelse som datamatiker :)
Avatar billede dragonknight Juniormester
07. december 2005 - 11:52 #10
Enig, og jeg har bare aldrig tænk på det på denne måde, og har ikke overblik over hvad der sker, skulle strømmen gå til den maskine, som har startet transaktion.

Nu er jeg ikke skarp på .NET, men kunne det ikke tænkes, at .NET ikke skriver noget som helst for efter en commit, ganske som i de gode gamle dage. Du skal huske, at med MySQL, der kører du direkte op mod databasen, og jeg har mistanke om, at det gør du ikke i .NET. Bare en tanke, men din lærer kan måske uddybe.
Jeg har også godt af at blive klogere en gang i mellem  :-)
Avatar billede arne_v Ekspert
08. december 2005 - 00:31 #11
.NET bør ikke lave noget behind the scene

det du har set svarer til transaction isolation level read uncommitted

måske kører du med det mens .NET  eksemplet bruger f.eks. repeatable read
transaction isolation level

og det er ikke nødvendigvis et problem i forbindelse med nedbrud - hvis
der når serveren startes op og laver recovery laves en rollback så ender
man alligevel i en konsistent tilstand
Avatar billede arne_v Ekspert
08. december 2005 - 00:32 #12
Avatar billede Slettet bruger
08. december 2005 - 05:54 #13
Det er dit isolation level, den er repetable read default, se følgende

http://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-isolation.html

du burde ikke opleve det du beskriver hvis du seææte isolation level til serializable.

Hvis det din lære har vist dig kørte som en COM+ transaction så vil det alt efter hvordan det var konfigureret kunne have køre med isolation level serializable.
Avatar billede webcreator Nybegynder
08. december 2005 - 09:48 #14
Både min lærer og jeg benytter et ISOLATION LEVEL der er SERIALIZABLE. Jeg udfører flg. inden min transaktion :

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE

Herefter følger min START TRANSACTION .......... COMMIT
Avatar billede webcreator Nybegynder
08. december 2005 - 09:49 #15
... det hjælper dog stadig ikke.
Det skal dog siges at han bruger MySQL 4.x mens jeg bruger 5.x
Avatar billede arne_v Ekspert
08. december 2005 - 21:19 #16
kryptos>

jeg forstår problemet som en dirty read og ikke en phantom read

webcreator>

kan du checke på en MySQL 4 - måske er det en lille hovsa
Avatar billede webcreator Nybegynder
08. december 2005 - 23:02 #17
Jeg har desværre ikke lige adgang til en MySQL 4
Avatar billede webcreator Nybegynder
08. december 2005 - 23:02 #18
Tror dog lige jeg prøver med .NETs Transaction klasse
Avatar billede arne_v Ekspert
08. december 2005 - 23:12 #19
du kan da vel bare hente og installere den på din PC ??
Avatar billede webcreator Nybegynder
09. december 2005 - 12:44 #20
Jo jo, men så skal jeg først lige finde et sted der har de forældede versioner. Dem er der sikkert rigeligt af. Men jeg tror lige jeg vil koncentrere mig om eksamens-løsning frem til på mandag hvor jeg skal op :)
Avatar billede webcreator Nybegynder
09. december 2005 - 13:07 #21
Jeg tror i øvrigt jeg kan udelukke en bug i databasen. Det virker nemlig fint med klassen MySQLTransaction fra MySQLs egen .NET Connector. Og som du selv sagde, arne, så sker der næppe noget "Behind the scene".
Avatar billede webcreator Nybegynder
05. marts 2006 - 13:38 #22
Lad os få lukket spørgsmålet - smid et svar, Arne :)
Avatar billede arne_v Ekspert
05. marts 2006 - 15:26 #23
ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester