[MySQL] Transactie over meerdere pagina's

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

  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11-2025

Deddiekoel

Gadget nerd

Topicstarter
Ik ben bezig om een reserveringssysteem in elkaar te zetten op basis van MySQL 5 & PHP 5. Door de genormaliseerde database moet ik voor een reservering meerdere queries uitvoeren. Dmv een transactie mag dit geen probleem zijn.
Het probleem waar ik nu wel tegenaan loop is hoe ik een transactie over meerdere pagina's kan laten lopen? Ik wil mijn gebruikers dus x pagina's voorschotelen die allemaal een stukje aan de database toevoegen, pas als alle pagina's goed zijn doorlopen en er goedkeuring is gegeven wil ik het zaakje committen naar de database.

Uitgaande van dit topic zou dit niet mogelijk zijn, maar dat topic stamt uit 2002. Is dit inmiddels wel mogelijk? Of moet ik naar een compleet andere technologie gaan kijken (J2EE of zo)?

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • JaQ
  • Registratie: Juni 2001
  • Laatst online: 13:49

JaQ

Je zou e.e.a. eerst in sessie variabelen zetten, daarna aan het einde pas de inserts/updates kunnen doen. Je insert alles dan nog steeds in 1 transactie...

Egoist: A person of low taste, more interested in themselves than in me


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11-2025

Deddiekoel

Gadget nerd

Topicstarter
Die optie staat inderdaad nog open, maar ik wil ook dat er feedback is naar andere gebruikers. Dus als ik bepaalde plaatsen boek dat diezelfde plaatsen niet door anderen kunnen worden geboekt.

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


Verwijderd

Maak een object die je in een session serialized.

dit object voert alle queries uit,
en op de laaste pagina doe je een commit (kijk uit dat je geen open transacties houd.. )

  • __fred__
  • Registratie: November 2001
  • Laatst online: 11-02 07:23
Omdat een transactie impliciet betekent dat je tabellen of rijen in een tabel lockt, wil je je transacties zo kort mogelijk laten duren. Ik zou een transactie dus niet meerdere pagina's lang open laten staan. Wat als iemand tussendoor koffie gaat drinken?
Tussentijds de wijzigingen bijhouden en in de laatste stap in een keer doen en committen.

  • ThaDaNo
  • Registratie: Mei 2002
  • Laatst online: 05-04-2023
Wat sommige ticketreserveringssites doen is de tickets een x aantal minuten vasthouden voor je en de tickets daarna weer vrijgeven.

Verwijderd

Die optie staat inderdaad nog open, maar ik wil ook dat er feedback is naar andere gebruikers. Dus als ik bepaalde plaatsen boek dat diezelfde plaatsen niet door anderen kunnen worden geboekt.
Dit ga je zowiezo niet voor elkaar krijgen met transacties. De meeste database transacties voldoen aan de ACID criteria. De 'I' staat voor Isolation, wat wil zeggen dat anderen de tussentijdse wijzigingen in de database niet zien, tot nadat de transactie is gecommit.

  • B-Man
  • Registratie: Februari 2000
  • Niet online
Wat anderen al aangegeven hebben: het is niet verstandig om transacties buiten je requests om open te laten staan. Sowieso is het op een multi-user systeem niet mogelijk met standaard PHP. De verbinding naar MySQL wordt namelijk aan het einde van een request gesloten, en daarmee krijgen impliciet alle nog openstaande transacties een ROLLBACK.

Mocht je nu denken aan persistent connections: no go. Die deel je namelijk met andere requests, dus dan gaan je queries voor verschillende bezoekers in dezelfde transactie terechtkomen.

De simpele oplossing is:
- Gedurende een aanvraag zaken in sessie opslaan, aan het einde een transactie waarin je alles verwerkt.
- Wil je terwijl er een aanvraag 'loopt' de website al wel die mogelijke aanvraag laten weerspiegelen, dan zul je een tijdelijke aanvraag moeten opslaan, die je middels een cronjob geregeld opschoont. Natuurlijk ook bij
a) opslaan definitieve aanvraag de tijdelijke aanvraag omzetten
b) cancellen aanvraag de tijdelijke aanvraag verwijderen
c) eventuele disconnects opvangen door een cronjob die tijdelijke aanvragen die 'oud' zijn (30 minuten? te verwijderen.

Je zit in deze context altijd met het probleem van tijdigheid: wil je
a) bij aanvang proces van aanvraag de randvoorwaarden van die aanvraag 'locken', en daarmee voorkomen dat de klant aan het eind een 'data al bezet' fout kan krijgen, of
b) niet locken, en het risico lopen dat de klant aan het einde van de aanvraag de melding krijgt dat de data niet vrij zijn.

Met a zit je met het fenomeen dat een drukbezocht aanvraagsysteem met veel afgekapte orders (venster sluiten), je veel 'bezet' ziet terwijl dat niet zo is, en met b met de vervelende eigenschap dat pas aan het einde van de aanvraag blijkt dat bepaalde randvoorwaarden niet beschikbaar zijn.

  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11-2025

Deddiekoel

Gadget nerd

Topicstarter
Het is dus duidelijk dat ik het beste in 1 keer naar de database moet gaan (dan wel met transacties).

Om het tijdelijke karakter op te vangen wil ik nu een AJAX paginaatje maken waarin het toekennen van plaatsen in een subscript zit. Mocht er dan aan het einde van de pagina blijken dat de plaatsen al vol zijn dan kan dat script opnieuw draaien voor een nieuwe mogelijkheid...

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


Verwijderd

Deddiekoel schreef op maandag 16 oktober 2006 @ 10:53:
Het is dus duidelijk dat ik het beste in 1 keer naar de database moet gaan (dan wel met transacties).
[...]
Het is inderdaad niet mogelijk om een transactie open te houden. Daarnaast is hierboven ook al aangegeven dat het geen wenselijke situatie is om een transactie zolang op te houden.

De stelling dat het dus het beste is om in 1 keer alles naar de database te schrijven is wat kort door de bocht. Dit ligt aan de requirements / wensen van de klant. Ik kan me voorstellen dat je een gebruiker wil laten zien dat er nog x plaatsen vrij zijn waarvan er y plaatsen op dit moment voor-gereserveerd zijn (ik weet niet hoe je dit wilt noemen :)).
Wat ik wil aangegeven is dat het dus niet beter is maar dat het geheel afhankelijk is van de eisen/wensen.

  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11-2025

Deddiekoel

Gadget nerd

Topicstarter
Ok, je hebt gelijk. De "dus" was ook gebaseerd op de argumenten erboven.

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


Verwijderd

Ok :)

Overigens maakt een AJAX applicatie het ook mogelijk om telkens te testen of er nog een reservering mogelijk is op basis van de geselecteerde criteria dus dit is ook goed mogelijk.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op maandag 16 oktober 2006 @ 11:42:
De stelling dat het dus het beste is om in 1 keer alles naar de database te schrijven is wat kort door de bocht. Dit ligt aan de requirements / wensen van de klant. Ik kan me voorstellen dat je een gebruiker wil laten zien dat er nog x plaatsen vrij zijn waarvan er y plaatsen op dit moment voor-gereserveerd zijn (ik weet niet hoe je dit wilt noemen :)).
Wat ik wil aangegeven is dat het dus niet beter is maar dat het geheel afhankelijk is van de eisen/wensen.
Nee het is niet afhankelijk van de eisen en wensen van de klant, het kan gewoon niet. Je kunt niet pure ACID transactions performant maken MET user interactie. Het is daarom een doodzonde om userinteractie te hebben midden in een lopende DB transactie. Want, wat gebeurt er als de user iets moet doen? Tijdverlies en in die tijd zijn de rows wel gelockt. Wat gebeurt er met die locks als de user eerst even koffie gaat halen voordat hij verder gaat?

Daarom moet je bij multi-page wizards met temp data werken die je of in-memory opslaat (voorkeur) of in een daarvoor bestemde table(s). De feitelijke transactie doe je op het laatst wanneer alles accoord is en dus zonder tussenkomst van wat dan ook. Elke consessie hieraan doet afbreuk aan je systeem en zet het gehele ACID karakter op de tocht. Het uberhaupt overwegen vind ik al discutabel.

Verder is het probleem van 'zijn er nog reserveringen over' etc. niet op te lossen zonder een claim structuur. Je zit nl. met stale data, dus je moet wel reserveringen reserveren, maar niet finalizen. DB locks daarvoor gebruiken is uit den boze want die blocken readers, tenzij je ranzige db code gebruikt die locks negeert bij het lezen.

[ Voor 10% gewijzigd door EfBe op 16-10-2006 12:12 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com

Pagina: 1