Toon posts:

[ASP.net / C#] - Sluiten venster alleen via button

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

Verwijderd

Topicstarter
Het probleem: ik heb een venster waar een knop op staat die het venster sluit. Doordat er dan een stukje servercode wordt aangeroepen (opheffen van een lock), moet deze worden aangeroepen. Als de gebruiker via ALT+F4 of het kruisje het venster sluit, wordt de lock niet opgeheven.

Ik wil dus dat het niet mogelijk is om op deze manier het venster te sluiten.

Ik heb het volgende topic al gevonden: [rml][ visual Basic 6.0]Formulier alleen minialiseren[/rml]
, maar dit is in VB en dus niet echt van toepassing op mij. Als ik zoek op google op close button e.d., vind ik niet wat ik zoek.

Wie kan mij helpen?

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Waarom roep je de code die de lock opheft ook niet gewoon aan als er op het kruisje gedrukt wordt?

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Verwijderd

Topicstarter
rwb schreef op dinsdag 04 oktober 2005 @ 12:14:
Waarom roep je de code die de lock opheft ook niet gewoon aan als er op het kruisje gedrukt wordt?
Hoe wilde je dat doen in ASP... Er wordt wel een event getriggerd, maar in javascript. En vanuit javascript kun je geen servercode aanroepen :)

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 02:26
Enige manier lijkt mij met javascript het windowCLose event afvangen, en daarin een venster openen die de lock opheft en zichzelf eventueel sluit.

Roomba E5 te koop


Verwijderd

Topicstarter
sig69 schreef op dinsdag 04 oktober 2005 @ 12:36:
Enige manier lijkt mij met javascript het windowCLose event afvangen, en daarin een venster openen die de lock opheft en zichzelf eventueel sluit.
Daar zat ik inderdaad ook aan te denken... Het is totaal niet mogelijk om het sluiten gewoon onmogelijk te maken? Vind ik wel een nettere manier eigenlijk.

  • Annie
  • Registratie: Juni 1999
  • Laatst online: 25-11-2021

Annie

amateur megalomaan

Wees maar blij dat je vanuit een webapplicatie niet kan zorgen dat het venster niet meer gesloten kan worden; dat zou héééle vervelende reclame pop-ups geven ;)

Je kan eens kijken naar het onunload en onbeforeunload (de laatste is IE only, afaik) event. Overigens is dat niet waterdicht.

Today's subliminal thought is:


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
idd. Je kunt bij een webapplicatie niet zorgen dat je je vensten niet kunt sluiten. Mischien dat je iets meer mogenlijkheden hebt als je het in hta draait ( wel IE only geloof ik. ).

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Verwijderd

Topicstarter
rwb schreef op dinsdag 04 oktober 2005 @ 12:56:
idd. Je kunt bij een webapplicatie niet zorgen dat je je vensten niet kunt sluiten. Mischien dat je iets meer mogenlijkheden hebt als je het in hta draait ( wel IE only geloof ik. ).
Hta?? B) :? Wat is dat?

Ik denk dat ik al iets weet, als het venster gesloten wordt, wordt het parentwindow gereload. Daar kan ik wel de methode aanroepen.

Verwijderd

Boland, ook hier vraag ik me af of je niets iets verschrikkelijk onlogisch doet. Wat voor lock is dit? En hoe hard is deze lock nodig? Zou een time out (bijv. via session_end event) niet genoeg zijn?

Verwijderd

Topicstarter
Verwijderd schreef op dinsdag 04 oktober 2005 @ 13:20:
Boland, ook hier vraag ik me af of je niets iets verschrikkelijk onlogisch doet. Wat voor lock is dit? En hoe hard is deze lock nodig? Zou een time out (bijv. via session_end event) niet genoeg zijn?
Nee hoor, is niet onlogisch, jammer dat je dat denkt...

De gebruiker ziet ingelogd een datagrid. Door op een item te klikken in deze datagrid worden in een popupvenster de details getoond en kan hij het item wijzigen. Het kan ook zijn dat 2 of meer verschillende gebruikers dezelfde datagrid bekijken en vervolgens de details van een item tegelijk bekijken en proberen te wijzigen. Om te voorkomen dat 2 gebruikers op het zelfde moment het record proberen te wijzigen, heb ik een lock ingebouwd.
Als bezoeker A het item opent, wordt een lock op het item gezet en zijn de velden wijzigbaar. Als bezoeker B hetzelfde item opent, krijgt hij een melding dat een andere bezoeker het record reeds aan het wijzigen is. Alle velden zijn nu readonly.
Na een timeout bij bezoeker A of het sluiten van het venster zorgt ervoor dat de lock opgeheven wordt.

Wel logisch lijkt me toch?
Boland, ik heb het idee dat je nog heel erg aan het leren bent in .Net, en dan is het misschien meer zinvol om in je topic uit te leggen wat je wil bereiken voordat je schrijft hoe je dat aangepakt hebt, want soms zal je aanpak onhandig zijn en is het gewenste effect makkelijker te bereiken maar weet jij nog niet hoe.
Uit een ander topic. Ik heb nu toch uitgelegd wat ik wil?

[ Voor 17% gewijzigd door Verwijderd op 04-10-2005 13:35 ]


Verwijderd

Ja, ik snap nu wat jij wil, maar belangrijker, welke functionaliteit je ermee wilt bereiken.

Het is in .Net juist gebruikelijk om met disconnected data te werken in datasets. Daarbij is het mogelijk dat meerdere users dezelfde gegevens wijzigen, maar dan is het veel zinvoller om de tijdens het opslaan van gegevens na te gaan of iemand anders de gegevens in de tussentijd heeft gewijzigd, waarbij je de gebruiker de mogelijkheid geeft om de wijziging alsnog op te slaan of te cancelen. Hiervoor zit er in .net datasets ondersteuning.

Als je dit persee wilt, kies je ook de mogelijke problemen die erbij horen. Aangezien web applicaties een van nature 'disconnected' protocol gebruiken (HTTP), is het voorkomen dat een gebruiker wegsurft een probleem. Je kan met client side script een gebruiker proberen te waarschuwen of tegen te houden, maar die kan zelf dit negeren of JavaScript uit hebben staan. Ook is er een kans dat, wanneer een gebruiker lang een item op 'edit' open heeft staan zonder er iets mee te doen, dat anderen hun werk niet kunnen doen. Deze oplossing moet je dus alleen kiezen als je er een hele goede reden voor hebt.

Je kunt (zoals ik aangaf) evt. het session_end event in global.aspx gebruiken om de locks weg te halen. Dit is mijns inziens de meest betrouwbare manier die je hiervoor kunt gebruiken. Als aanvulling erop kan je via JavaScript de gebruiker een waarschuwing kunnen geven ("U heeft nog geopende items. wilt u deze eerst afsluiten?" met ok / cancel), waarbij de gebruiker alsnog kan kiezen uit edit mode te gaan voor hij wegsurft.

Succes :)

[ Voor 8% gewijzigd door Verwijderd op 04-10-2005 13:58 ]


Verwijderd

Topicstarter
:) Ik heb het expres niet in de startpost gemeld, aangezien het niet echt relevant was dacht ik.

Ik mag het systeem dat ik aan het maken ben eigenlijk niet uitleggen. Het komt er op neer dat er 2 gebruikertypen zijn, klanten en medewerkers. Klanten melden problemen aan, medewerkers kunnen deze problemen dan zien en wijzigen. Klanten kunnen problemen gedeeltelijk wijzigen (bijv. aangeven dat het probleem nu opgelost is), medewerkers kunnen problemen geheel wijzigen (bijv. aangeven wanneer het probleem opgelost zal zijn, wie er mee bezig is, e.d.).

Als een klant een probleem wijzigt, mag een medewerker niet tegelijkertijd het probleem wijzigen. Dit zal bijna nooit voorkomen, daarom vond ik mijn oplossing netter. Anders zou het voor kunnen komen dat werk voor niets is.

Over het feit dat een lock te lang wordt behouden, hiervoor had ik de volgende oplossing:

- Sessietimeout op ong. 5 minuten.
- Als het venster wordt afgesloten, wordt de lock opgeheven (wordt door een reload van het parent window afgevangen). Hier is wel javascript voor nodig, als de gebruiker niet heeft, is dit inderdaad een probleem.

Je hebt gelijk dat dit niet de intentie is van .Net, maar het is in mijn geval wel de netste oplossing.

[ Voor 5% gewijzigd door Verwijderd op 04-10-2005 14:32 ]


  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 22:35

TeeDee

CQB 241

Je zou met AJAX het e.e.a. kunnen regelen wat betreft je "lock" probleem. Hier runnen we ook een webapplicatie die om de 2 sec. pollt. Geen probleem.

Doordat je met AJAX werkt, zou je evt. ook serverside e.e.a. kunnen regelen.

Als een user JS uit heeft staan, komt het .net framework toch met een melding?
Weet ik niet zeker. Dacht dat ik het een keer voorbij zag komen. Als dat zo is, dan is het volgens mij IE only. In FireFox kreeg ik inderdaad geen melding.

[ Voor 28% gewijzigd door TeeDee op 04-10-2005 14:56 ]

Heart..pumps blood.Has nothing to do with emotion! Bored


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 29-04 08:14

Janoz

Moderator Devschuur®

!litemod

Het is zeker neit de netste oplossing. Doordat je nu de sessietimeout op 5 min hebt gezet haal je vervolgens een bak nieuwe problemen op je hals. Het is absoluut niet ondenkbaar dat het wijzigen van een melding meer dan 5 minuten kost. Denk hierbij aan het verivieren van een bepaalde melding in een ander scherm, het telefonisch overleggen terwijl je wat aanpast of eventueel het halen van een kop koffie.

Nu kun je dat wel weer oplossen door een keepalive javascriptje oid te runnen die constant de sessie ververst, maar ik hoop dat je zo langzamerhand het patroon ook ziet.

Jij bent bezig om je eigen onjuiste keuze met lapmiddelen werkend te krijgen. 1000-den mensen hebben dit probleem ook gehad en hieruit is uiteindelijk een oplossing naar voren gekomen die in dit soort gevallen gewoon het beste werkt.
Ik heb het expres niet in de startpost gemeld, aangezien het niet echt relevant was dacht ik.
Dit is JUIST de relevante informatie. Ik zie het zelf erg vaak om mij heen gebeuren dat mensen met een bepaalde tunnelvisie naar een probleem kijken. Er is een bepaald pad gekozen en men probeert met allerlei lapmiddelen de boel aan elkaar te breien. Soms is het beter om even een stapje terug te doen en een eerdere keuze te heroverwegen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
Janoz schreef op dinsdag 04 oktober 2005 @ 14:40:
Het is zeker neit de netste oplossing. Doordat je nu de sessietimeout op 5 min hebt gezet haal je vervolgens een bak nieuwe problemen op je hals. Het is absoluut niet ondenkbaar dat het wijzigen van een melding meer dan 5 minuten kost. Denk hierbij aan het verivieren van een bepaalde melding in een ander scherm, het telefonisch overleggen terwijl je wat aanpast of eventueel het halen van een kop koffie.

Nu kun je dat wel weer oplossen door een keepalive javascriptje oid te runnen die constant de sessie ververst, maar ik hoop dat je zo langzamerhand het patroon ook ziet.

Jij bent bezig om je eigen onjuiste keuze met lapmiddelen werkend te krijgen. 1000-den mensen hebben dit probleem ook gehad en hieruit is uiteindelijk een oplossing naar voren gekomen die in dit soort gevallen gewoon het beste werkt.


[...]


Dit is JUIST de relevante informatie. Ik zie het zelf erg vaak om mij heen gebeuren dat mensen met een bepaalde tunnelvisie naar een probleem kijken. Er is een bepaald pad gekozen en men probeert met allerlei lapmiddelen de boel aan elkaar te breien. Soms is het beter om even een stapje terug te doen en een eerdere keuze te heroverwegen.
Hoe zou jij het dan doen? Ik zie de lapmiddelen niet echt, enige wat niet netjes is dat de lock opgeheven wordt in het parent window. Dat een 2e gebruiker het item niet kan wijzigen, is oke volgens mijn opdrachtgever.

Er wordt nu na de sessie-timeout een popup getoond of de gegevens opgeslagen moeten worden, de gebruiker heeft x seconden de tijd om te reageren. Als er niet gereageerd wordt binnen de x seconden worden de gegevens niet opgeslagen. Jammer dan, maar het zijn maar 15 velden en het is gemakkelijk binnen die 5 minuten in te vullen. Het zijn geen 100 velden die ingevuld moeten worden.
TeeDee schreef op dinsdag 04 oktober 2005 @ 14:36:
Je zou met AJAX het e.e.a. kunnen regelen wat betreft je "lock" probleem. Hier runnen we ook een webapplicatie die om de 2 sec. pollt. Geen probleem.

Doordat je met AJAX werkt, zou je evt. ook serverside e.e.a. kunnen regelen.

Als een user JS uit heeft staan, komt het .net framework toch met een melding?
Ik heb al een keer eerder naar AJAX gekeken inderdaad, maar aangezien het nu ook werkt, zie ik de noodzaak nog niet om het op die manier te doen.

Ik weet niet of de gebruiker een melding krijgt als JS uitstaat... Ik heb dat nog niet getest.

[ Voor 40% gewijzigd door Verwijderd op 04-10-2005 14:58 ]


Verwijderd

Als ik kijk naar het functionele doel van deze applicatie, dan ben ik eigenlijk tegen het aanbrengen van wijzigingen. Men zou updates / aanvullingen moeten kunnen doen op een bestaande call. Het wijzigen van eerdere berichten werkt "fraude" in de hand.

Om een goede audit te kunnen doen op een call is het belangrijk om ook precies de volgorde van het melden van gegevens te kunnen terughalen. Als een klant eerst iets niet meldt, de medewerker daardoor het probleem niet vindt, en de gebruiker ondertussen informatie toevoegt, dan moet het ook duidelijk zijn waarom de call eerst niet en later wel opgelost zou kunnen worden.

Kortom, ik zou dit anders ontwerpen.

Verwijderd

Topicstarter
Verwijderd schreef op dinsdag 04 oktober 2005 @ 15:11:
Als ik kijk naar het functionele doel van deze applicatie, dan ben ik eigenlijk tegen het aanbrengen van wijzigingen. Men zou updates / aanvullingen moeten kunnen doen op een bestaande call. Het wijzigen van eerdere berichten werkt "fraude" in de hand.

Om een goede audit te kunnen doen op een call is het belangrijk om ook precies de volgorde van het melden van gegevens te kunnen terughalen. Als een klant eerst iets niet meldt, de medewerker daardoor het probleem niet vindt, en de gebruiker ondertussen informatie toevoegt, dan moet het ook duidelijk zijn waarom de call eerst niet en later wel opgelost zou kunnen worden.

Kortom, ik zou dit anders ontwerpen.
Dit zou inderdaad mooier zijn, maar gezien de vaste structuur van de database zou een history niet direct mogelijk zijn. Ik heb een design geschreven van het systeem dat ik maak en dat is goedgekeurd. In het ontwerp is hier wel rekening mee gehouden; een klant kan alleen een probleemmelding wijzigen totdat een medewerker deze heeft gezien. Daarna is de melding voor de klant read-only. Mocht het probleem nog niet duidelijk zijn voor de medewerker, kan er altijd telefonisch contact worden opgezocht.

Dat hij voordat een medewerker de melding ziet deze melding wijzigt, lijkt me geen probleem. Hij kan dan bijv. typfouten eruit halen. Het zijn klanten van het bedrijf waarvoor ik de opdracht doe, zij willen ook dat hun probleem z.s.m. wordt opgelost.

Nogmaals, ik weet het, het kan allemaal mooier en sophisticater en weet ik veel wat, maar dat gaat niet werken. Het moet in 10 weken af, aangezien het een stageopdracht is. Tevens is dit de eerste keer dat ik in ASP.NET programmeer, dus ik weet ook nog niet alle tricks e.d. Ik ben al lang blij dat ik in 3 weken al een redelijk werkend systeem in elkaar heb gezet.

Verwijderd

Boland: Ik bedoel geen van mijn posts als aanval op jouw of jouw kwaliteiten. Sterker nog, ik vind het knap hoe snel je ASP.Net lijkt op te pakken. Ik wil je echter wel bewust maken van de gevolgen van bepaalde ontwerpbeslissingen.

Als je je daar bewust van bent, maar toch redenen hebt om de eerder bedachte oplossing te kiezen, dan is dat prima. Ik denk ook dat het geen onverstandige keuzes zijn aan de hand van de randvoorwaarden die jij hier schetst, maar met andere randvoorwaarden zou dat heel anders kunnen zijn. Het juist kunnen inschatten daarvan is een kwestie van ervaring, en daarom dat ik mijn opmerkingen plaats (en ook Janoz, vermoed ik). Daarom vind ik het nuttig om die randvoorwaardes boven tafel te krijgen, zeker als er een wat gekunstelde oplossing gekozen wordt, omdat anders het puur beantwoorden van de vraag je alleen maar verder van huis zouden brengen.

Als je een oplossing kiest zonder je bewust van de gevolgen en problemen te zijn, zal dat onvermijdelijk leiden tot veel problemen die je nauwelijks aan je klant zult kunnen uitleggen. Als je bij iedere keuze met redelijk grote gevolgen de klant betrekt, zal hij uiteindelijk ook de gevolgen van die keuzes accepteren, ook als later daardoor problemen ontstaan. En dit is iets heel belangrijks voor alle ontwikkelaars om te beseffen, en wellicht kan jij ervan leren.

[ Voor 15% gewijzigd door Verwijderd op 04-10-2005 15:43 ]


Verwijderd

Topicstarter
@MrX, bedankt! Dat ik bepaalde dingen zo snel heb geleerd komt ook door jullie hier... Ik heb al redelijk wat topics geopend en door de reacties heb ik veel ervaring opgedaan. Alsnog bedankt hiervoor _/-\o_.

Ik vatte het ook niet op als een aanval. Ik begrijp wel dat jullie mijn ontwerpbeslissingen misschien niet helemaal begrijpen, maar ik werk alleen het ontwerp uit wat ik in het begin heb gemaakt. Doordat ik toen totaal niet ervaren was met ASP wist ik niet dat ik nu tegen deze problemen aan zou lopen. Nu ik meer ervaring heb, zal ik de volgende keer deze fouten niet weer maken.

Zoals het systeem nu werkt:

- De gebruiker logt in en na het kiezen van een project wordt een lijst met problemen getoond
- Door op een probleem te klikken, wordt een popup getoond waar de gebruiker dit specifieke probleem kan wijzigen (en extra details krijgt). Er wordt een lock op dit probleem gezet. Als een andere gebruiker dit probleem wil bekijken, zal hij hiervan een melding krijgen en zijn alle velden read-only. Door een refresh zou hij opnieuw kunnen checken of het probleem weer 'vrij' is.
- Na een timeout of het sluiten van het venster zal een reload van het parentform (met de lijst met problemen) plaatsvinden, in de PageOnLoad wordt de lock opgeheven.

Probleem: een gebruiker die de details opent van 1 probleem, kan dit ook doen om de details te bekijken en verder geen wijzigingen doorvoeren. Echter, doordat dit bijna niet voorkomt, is dit volgens mij geen probleem. Ik zal dit nog melden aan mijn stagebegeleider.

Netter is:

De lock wordt pas gezet bij het daadwerkelijk wijzigen. Dit is gevoelsmatiger en volgens het principe van .Net ook meer voor de hand liggend. Probleem is hierbij natuurlijk wel als het volgende gebeurt:
- Gebruiker 1 opent de details en begint alle velden te wijzigen. Gebruiker 2 opent de details en doet hetzelfde. Gebruiker 1 submit het formulier, even later gebruiker 2. De wijzigingen van gebruiker 1 zijn nu ongedaan gemaakt. Echter, het is wel zo dat alleen medewerkers alle velden kunnen wijzigen, een klant kan bijna niets wijzigen nadat een medewerker iets gezien heeft. Gebruiker 1 en 2 zullen ook bijna nooit 2 medewerkers zijn, dus op zich is deze oplossing wel te implementeren. Het probleem van verloren gegane gegevens door kort opvolgende submits blijf je houden. Dit probleem is vast al veel ouder, ik zal jullie daarom ook niet vragen hoe ik dit moet oplossen aangezien ik zelf nog niet heb gezocht.

Mijn vraag is nog wel, wat is niet netjes aan mijn oplossing? Ik vermoed deze 3 punten:

- Lock opheffen in parent m.b.v. javascript
- Lock wordt niet opgeheven als JS uitstaat.
- Lock hoort pas aangeroepen te worden bij daadwerkelijke update en niet bij het openen van het detailvenster.

Verwijderd

Verwijderd schreef op dinsdag 04 oktober 2005 @ 15:58:
[...]
Mijn vraag is nog wel, wat is niet netjes aan mijn oplossing? Ik vermoed deze 3 punten:

- Lock opheffen in parent m.b.v. javascript
- Lock wordt niet opgeheven als JS uitstaat.
- Lock hoort pas aangeroepen te worden bij daadwerkelijke update en niet bij het openen van het detailvenster.
Afhankelijk zijn van client-side code voor het correct werken van je applicatie is IMHO nooit netjes, omdat je namelijk geen controle hebt over de client.

Client side script zou extra's moeten bieden, meer niet. Uitzonderingen zijn applicaties waarbij de interactiviteit van client-side script essentieel is voor het gebruik, zoals Google's EarthViewer, maar eerlijk gezegd vind ik dat een beetje gekunsteld gebruik van de webbrowser. Voor een administratieve applicatie zou client-side script niet benodigd moeten zijn.

Ik zou, naast de client-side code, ook in het Session_End event in Global.asax wat code plaatsen om evt. een lock te verwijderen. Zet de session time out niet korter dan de standaard 20 minuten, want dat levert weer andere issues op, maar zorg wel dat er een time out is, zodat je altijd (nou ja, bijna altijd, je moet niet denken aan een server crash) de lock verwijdert. Beter na 20 minuten dan nooit. Zo maak je de applicatie niet / minder afhankelijk van client-side script.

[ Voor 29% gewijzigd door Verwijderd op 04-10-2005 16:52 ]


Verwijderd

Topicstarter
In Global.asax wordt na Session_End de lock ook verwijderd :)

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 29-04 08:14

Janoz

Moderator Devschuur®

!litemod

Mijn vraag is nog wel, wat is niet netjes aan mijn oplossing?
Wat niet netjes is, is dat je in een request/response http omgeving een lock gebruikt. Er zullen dan altijd gebruikers zijn die tegen problemen aanlopen omdat de timeout te lang is (gelockte records die niet kunnen worden gewijzigd) of juist te kort (wijzigingen die niet kunnen worden doorgevoerd omdat een gebruiker te lang heeft gedaan over het invullen van het formulier). Daarnaast zal er zo af en toe altijd een record door de controle vliegen (door welke bug of hickup dan ook) die niet gereleased wordt en daardoor altijd gelockt blijft.

Bij software ontwerp zul je altijd uit moeten gaan van Murphies law : "Averything that can go wrong, will go wrong"
Het probleem van verloren gegane gegevens door kort opvolgende submits blijf je houden.
Een lock is niet de enige oplossing. Een andere is bijvoorbeeld het aanbieden van een merge scherm. Wanneer je bijhoud wanneer een record voor het laatst geupdate is, en je houd in je formulier bij wanneer de gegevens zijn opgevraagd, (eventueel met volgnummer dat via een trigger opgehoogd wordt) kun je detecteren of een record eventueel gewijzigd is terwijl je zelf in je formulier bezig was. Je kunt dan als feedback aan de gebruiker een scherm tonen waarop zijn eigen gegevens staan en de huidige database versie. De gebruiker kan vervolgens kiezen welke aanpassingen hij/zij op wil slaan.


EDIT: Hmm, deze reply had ik een kwartier eerder al getikt, maar nu pas gesubmit. Somige dingen in het eerste stuk zijn ook al door MrX behandeld

[ Voor 5% gewijzigd door Janoz op 04-10-2005 17:13 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Wat wij doen is redeljik vergelijkbaar.
Zodra je een pagina / call gaat wijzigen wordt er een lock geplaatst.
Deze lcok slaat de gebruiker op en toont een sleuteltje.

Zodra de gebruiker opslaat, wordt het lock geleegd. In de tussentijd kan de pagina dus niet in edit-mode.
Tot dusver dus gelijk aan de info van TS.

Als de gebruiker annuleert etc. wordt de lock ook verwijderd. Onunload wordt ook afgevangen, maar is zoals eerder vermeld niet helemaal 100%

Mocht een gebruiker dus Alt+F4 gebruiken, dan staat het document nog gelockt onder zijn / of haar naam. Bij 50.000 gebruikers komt dit bij ons zelden voor.
Om te zorgen dat de applicatie niet in de soep loopt hierdoor worden alle locks 's-nachts vrijgegeven (we gaan ervan uit dat 's-nachts niet gewerkt wordt ;) )

Wellicht heb je er wat aan, andere mogelijkheid is die postbank.nl gebruikt en dat is bij het sluiten een pop-up starten met "een ogenblik aub..." In deze pop-up zet je alles recht en verwijder je de lock.

Echt 100% safe krijg je het niet en in mijn ogen blijft dit nog wel even een browserprobleem...

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Verwijderd schreef op dinsdag 04 oktober 2005 @ 21:34:
Om te zorgen dat de applicatie niet in de soep loopt hierdoor worden alle locks 's-nachts vrijgegeven (we gaan ervan uit dat 's-nachts niet gewerkt wordt ;) )
Dan kan je beter bij het aflopen van een Session de lock van de user vrij geven. Als zijn session is afgelopen heeft hij er toch te lang over gedaan.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Verwijderd

Topicstarter
Wat niet netjes is, is dat je in een request/response http omgeving een lock gebruikt. Er zullen dan altijd gebruikers zijn die tegen problemen aanlopen omdat de timeout te lang is (gelockte records die niet kunnen worden gewijzigd) of juist te kort (wijzigingen die niet kunnen worden doorgevoerd omdat een gebruiker te lang heeft gedaan over het invullen van het formulier). Daarnaast zal er zo af en toe altijd een record door de controle vliegen (door welke bug of hickup dan ook) die niet gereleased wordt en daardoor altijd gelockt blijft.

Bij software ontwerp zul je altijd uit moeten gaan van Murphies law : "Averything that can go wrong, will go wrong"
Dat een record door de controle vliegt, kan dat? Dan zou het hele systeem bij wijze van spreken kunnen crashen... Ik maak gebruik van het Application- en het Session-object. In het Application-object wordt een Arraylist bijgehouden met gelockte record. In het Session-object wordt een string bijgehouden met het record dat de gebruiker heeft gelockt (om meerdere locks bij 1 gebruiker te voorkomen). Bij het wijzigen van de Arraylist wordt m.b.v. Application.Lock gezorgd dat de arraylist niet door 2 gebruikers tegelijkertijd gewijzigd wordt.

Tuurlijk, er kan iets misgaan, maar volgens mij zit het zo waterdicht in elkaar.
Een lock is niet de enige oplossing. Een andere is bijvoorbeeld het aanbieden van een merge scherm. Wanneer je bijhoud wanneer een record voor het laatst geupdate is, en je houd in je formulier bij wanneer de gegevens zijn opgevraagd, (eventueel met volgnummer dat via een trigger opgehoogd wordt) kun je detecteren of een record eventueel gewijzigd is terwijl je zelf in je formulier bezig was. Je kunt dan als feedback aan de gebruiker een scherm tonen waarop zijn eigen gegevens staan en de huidige database versie. De gebruiker kan vervolgens kiezen welke aanpassingen hij/zij op wil slaan.
Dit is een goede inderdaad! Je houdt het probleem nog steeds wel denk ik... Stel dat er 3 gebruikers inloggen en hetzelfde record openen:

- Gebruiker A voert wijzigingen door.
- Gebruiker B voert wijzigingen door en krijgt het merge scherm.
- Tegelijk voert gebruiker C wijzigingen door en krijgt hetzelfde merge scherm als B. Dit zou niet mogen, aangezien je dan weer het probleem krijgt dat 1 van de 2 wijzigingen niet door zou kunnen komen. Hier zou je er ook weer een lock op kunnen zetten, maar stel dat B dan niets met het merge scherm doet :).

Oke, wel uitzonderlijk geval, maar het blijft al met al een probleem. Toch vind ik dit een zeer nette oplossing, zo had ik er nog niet naar gekeken. Ik zal er naar kijken als ik alles werkend heb, als soort van update :).
Wellicht heb je er wat aan, andere mogelijkheid is die postbank.nl gebruikt en dat is bij het sluiten een pop-up starten met "een ogenblik aub..." In deze pop-up zet je alles recht en verwijder je de lock.
Dit wordt ook in Javascript gedaan neem ik aan? Wordt OnUnload niet aangeroepen als je m.b.v. ALT+F4 het venster sluit??

Verwijderd

Je houdt het probleem nog steeds wel denk ik... Stel dat er 3 gebruikers inloggen en hetzelfde record openen:
Dat is geen probleem als de save functionaliteit in het merge scherm hetzelfde doet als in het reguliere edit scherm. Als de data al veranderd is door een andere gebruiker presenteer je opnieuw het merge scherm.

Verwijderd

Topicstarter
Verwijderd schreef op woensdag 05 oktober 2005 @ 12:47:
[...]


Dat is geen probleem als de save functionaliteit in het merge scherm hetzelfde doet als in het reguliere edit scherm. Als de data al veranderd is door een andere gebruiker presenteer je opnieuw het merge scherm.
Zie het als het volgende:

Bezoekers A, B en C zien hetzelfde record (zelfde gegevens).

A wijzigt iets en slaat het op.

B wijzigt iets en krijgt de melding dat er iets veranderd is en krijgt het merge scherm. 1 seconde later wil C zijn wijzigingen doorvoeren. Als dan ook het mergescherm getoond zou worden, zijn de wijzigingen van B nog niet verwerkt.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Verwijderd schreef op woensdag 05 oktober 2005 @ 12:58:
[...]

Zie het als het volgende:

Bezoekers A, B en C zien hetzelfde record (zelfde gegevens).

A wijzigt iets en slaat het op.

B wijzigt iets en krijgt de melding dat er iets veranderd is en krijgt het merge scherm. 1 seconde later wil C zijn wijzigingen doorvoeren. Als dan ook het mergescherm getoond zou worden, zijn de wijzigingen van B nog niet verwerkt.
Dan submit B dus zijn merge en C zit in hetzelfde Merge scherm. C probeert zijn merge te submitten en krijgt een nieuw merge scherm met de gegevens die hij wilde submitten en de gegevens die B heeft ingevoerd.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Verwijderd

Topicstarter
rwb schreef op woensdag 05 oktober 2005 @ 13:03:
[...]

Dan submit B dus zijn merge en C zit in hetzelfde Merge scherm. C probeert zijn merge te submitten en krijgt een nieuw merge scherm met de gegevens die hij wilde submitten en de gegevens die B heeft ingevoerd.
Ja, dat kan :) Maar in theorie kun je dan in een oneindige loop van mergeschermen komen :) Kan wel eens irritant worden, maar in de praktijk werkt het wel.

Verwijderd

Nogmaals :-) dat is geen probleem, zolang de save functionaliteit van je merge scherm ook checkt of de huidige versie van de data de meest recente is.

Gebruiker B en C hebben beide een merge scherm voor hun neus met de data in de database zoals opgeslagen door A en data met hun eigen wijzigingen.

Gebruiker B merget en slaat de boel op zoals hij/zij wenst. Dat gaat goed. Gebruiker C slaat vervolgens zijn merge versie op, maar krijgt opnieuw het merge scherm gepresenteerd. Dit merge scherm bevat de originele data uit de database, zoals opgeslagen door B, en de door C gewijzigde versie van deze data. Gebruiker C kan opnieuw mergen en opslaan en nu wordt de wijziging wel geaccepteerd.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 29-04 08:14

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op woensdag 05 oktober 2005 @ 13:07:
[...]

Ja, dat kan :) Maar in theorie kun je dan in een oneindige loop van mergeschermen komen :) Kan wel eens irritant worden, maar in de praktijk werkt het wel.
Je kunt alleen in een oneindige lus komen wanneer er een oneindig aantal mensen hetzelfde record edit. Zodra de database gewijzigd is heeft 1 iemand zijn veranderingen doorgevoerd en is zijn edit afgelopen. Bij N mensen heeft 1 iemand dan zijn wijziging doorgevoerd en krijgen N-1 mensen het merge scherm. Dit betekend dat de laatste persoon maximaal N keer het merge scherm voor zijn neus kan krijgen.


--

Dit hele systeem is trouwens simpel te implementeren door:
- een last changed datumfeld aan je record toe te voegen
- je update query uit te breiden met where lastChanged < formTimeStamp en een lastChanged = now()
- je select query uitbreiden zodat deze ook now() oplevert
- een merge versie van het formulier te maken die wordt opgeroepen als het record niet geupdate is en hierin de gesubmitte gegevens en de huidige versie in de DB weergeeft


Vier simpele, atomaire en goed controleerbare onderdelen en je hebt de hele functionaliteit afgedekt, zelfs bij N mensen die tegelijkertijd het record proberen te wijzigen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
Janoz schreef op woensdag 05 oktober 2005 @ 13:19:
[...]


Je kunt alleen in een oneindige lus komen wanneer er een oneindig aantal mensen hetzelfde record edit. Zodra de database gewijzigd is heeft 1 iemand zijn veranderingen doorgevoerd en is zijn edit afgelopen. Bij N mensen heeft 1 iemand dan zijn wijziging doorgevoerd en krijgen N-1 mensen het merge scherm. Dit betekend dat de laatste persoon maximaal N keer het merge scherm voor zijn neus kan krijgen.
Ja, dit bedoelde ik ook...
Janoz schreef op woensdag 05 oktober 2005 @ 13:19:
Dit hele systeem is trouwens simpel te implementeren door:
- een last changed datumfeld aan je record toe te voegen
- je update query uit te breiden met where lastChanged < formTimeStamp en een lastChanged = now()
- je select query uitbreiden zodat deze ook now() oplevert
- een merge versie van het formulier te maken die wordt opgeroepen als het record niet geupdate is en hierin de gesubmitte gegevens en de huidige versie in de DB weergeeft


Vier simpele, atomaire en goed controleerbare onderdelen en je hebt de hele functionaliteit afgedekt, zelfs bij N mensen die tegelijkertijd het record proberen te wijzigen.
Oke, dit gaat me echt boven de pet. Punt 1 snap ik nog, maar daarna wordt het wat grijzer...

Punt 2: Waarom vergelijk je op lastChanged? Er is toch maar 1 record voor het probleemite, waarom zou je dan deze whereclause toevoegen?
Punt 3: now() = current time? Dat hoeft toch niet via de database? Of bedoel je hier het veld lastChanged.
Punt 4: Dit moet toch zijn als het record wel geupdate is? Als het record niet geupdate is, hoeft er ook geen mergevenster getoond te worden lijkt me...

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 29-04 08:14

Janoz

Moderator Devschuur®

!litemod

Verwijderd schreef op woensdag 05 oktober 2005 @ 13:41:
[...]

Ja, dit bedoelde ik ook...

[...]

Oke, dit gaat me echt boven de pet. Punt 1 snap ik nog, maar daarna wordt het wat grijzer...

Punt 2: Waarom vergelijk je op lastChanged? Er is toch maar 1 record voor het probleemite, waarom zou je dan deze whereclause toevoegen?
Op die manier worden er 0 records geupdate wanneer de laatste verandering heeft plaatsgevonden nadat je het record hat opgehaald om het formulier te vullen. Als er dus 0 records geupdate zijn kun je je merge traject in.
Punt 3: now() = current time? Dat hoeft toch niet via de database? Of bedoel je hier het veld lastChanged.
Ja, zodra je update zet je het lastchanged veld op de huidige tijd (of je gebruikt een volgnummer). Waar wilde je dat anders opslaan? Eventueel doe je dit dmv een trigger zodat je hier geen fouten mee kunt maken in de applicatie (een query vergeten aan te passen ergens)
Punt 4: Dit moet toch zijn als het record wel geupdate is? Als het record niet geupdate is, hoeft er ook geen mergevenster getoond te worden lijkt me...
Met niet geupdate bedoel ik dat je eigen aanpassing niet verwerkt kon worden en die update dus niet heeft plaatsgevonden. Dit wordt inderdaad veroorzaakt doordat iemand anders dat record in de tussentijd geupdate heeft.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
Bedankt, zo is het inderdaad een stuk duidelijker!

Probleem is dat ik de database niet kan aanpassen... Ik werk niet direct op een database bij updates, ik schrijf xml-scripts die vervolgens door een scriptserver worden afgehandeld. Die server zorgt weer voor de afhandeling in de database.
Ja, zodra je update zet je het lastchanged veld op de huidige tijd (of je gebruikt een volgnummer). Waar wilde je dat anders opslaan? Eventueel doe je dit dmv een trigger zodat je hier geen fouten mee kunt maken in de applicatie (een query vergeten aan te passen ergens)
Dit is wel de beste oplossing inderdaad, zo zou ik het ook gedaan hebben. Ik snapte alleen niet wat je bedoelde :). Ik heb nog nooit met triggers gewerkt, bedoel je een trigger dat bij een willekeurige update automatisch het lastchanged-veld wordt geset?
Pagina: 1