Toon posts:

[VB6 ADO,SQLserver] Geen data uitlezen bij een updatelock

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig voor een project om een vb client-server applicatie te bouwen. We gebruiken hiervoor ADO en SQL server 2000.

Als een gebruiker bij een scherm een record wil gaan wijzigen, zal dit record eerst gelockt worden. We doen dit op de volgende manier:

UPDATE .....
SET ID = 2
WHERE ID =2


Dit gaat allemaal gewoon goed.

Nu komt het probleem. Als we dus een record gelockt hebben en vervolgens dezelfde applicatie nog een keer gaan draaien dan loopt die applicatie vast. Stel er zijn 5 records en het 3e record hebben we gelockt bij de eerste applicatie.

De 2e applicatie zal dan de 1e 2 records wel kunnen uitlezen, maar bij de 3e blijft die wachten totdat de gebruiker de lock (dus transactie) heeft opgeheven. Dan zal de 2e applicatie de volgende records ook kunnen uitlezen.

Het probleem is dus dat die bij die update lock dus ook een read lock op een of andere wijze toepast. Maar ik wil alleen een write lock hebben zodat ik dus wel de records uit kan lezen ondanks dat deze locked is.

Is dit mogelijk?

  • whoami
  • Registratie: December 2000
  • Nu online
* whoami snapt iets niet goed....

je doet een Update op een bepaalde tabel, en je zet ID = 2 voor de records waar ID = 2 ? :?

Een lock moet zo kort mogelijk zijn:
code:
1
2
3
lock record
update record
release record

https://fgheysels.github.io/


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Je moet functionaliteit locken. Dus een tabel maken met functionaliteitID's en daarachter of die gelockt zijn (en wellicht kunnen meerdere mensen ergens bij, bv wel users wijzigen maar niet dezelfde user). Start iemand bv userwijzigen en kiest user 1, dan mag een andere user dat dus niet doen, en moet de applicatie dus in de database kunnen zien dat userwijzigen met user 1 gelockt is en de functionaliteit dus niet kan worden gebruikt, op user 1. Zet een timestamp in het record die de locks registreert zodat je timeouts kunt regelen. Dit geheel kun je in een aparte class stoppen en overal in je applicatie dan toepassen. Concurrency is een lastig iets en dat moet je solide oplossen. Op basis van database locks is niet solide, want dat voorkomt nl;. niet dat meerdere mensen records dezelfde records wijzigen.

whoami: hij draait het in een transactie. Hij update het record met dezelfde info, wijzigt dus niets, maar door de update wordt het record wel gelockt binnen de transactie, en dus kan niemand er dan bij totdat de transactie is voltooid.

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


Verwijderd

Ik ben ook een teamlid van de groep die aan dit project werkt.

De gebruiker drukt dus op een knop waardoor hij in de edit-mode komt. Ik wil dus dat er ondertussen niet iemand anders dat record wijzigt, omdat dan alle wijzigingen door deze persoon voor niks worden gedaan.

Daarom voeren we dus eerst die update query uit, zodat niemand anders het record kan verwijderen of wijzigen.

Maar het probleem is dus dat hierdoor het record niet alleen voor het schrijven gelockt wordt, maar dat het ook niet mogelijk is voor andere personen om het record te lezen.

We willen dus alleen een write/delete lock en geen read lock.

Verwijderd

Topicstarter
Het idee van EfBe om een eigen transactie tabel neer te zetten is een mogelijkheid

Maar aan de andere kant, waarom zal je zelf een transactie tabel maken als de transactie mogelijkheid al ingebouwd is? De mensen van microsoft hebben een transactie systeem voor dit soort doeleinden gemaakt zodat het voor ons veel werk en tijd scheelt natuurlijk. Om die reden lijkt het ons niet verstandig om deze optie te implementeren.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Tokkie: precies: je moet functioneel voorkomen dat meerdere mensen bij hetzelfde record op 'edit' kunnen klikken. Dit moet je in je applicatie inbouwen, dus dat wanneer persoon A op 'edit' klikt bij record 1, in een tabel gelogd wordt dat A record 1 aan het editen is, en user B dus wel op edit kan klikken maar een foutmelding krijgt. Dit loggen kun je met een serialized transaction doen, waardoor altijd maar 1 user een zekere row kan toevoegn aan die log table. Wat jij doet is een record via sqlserver locks vasthouden, maar dat is t.a.t. af te raden.

kchong: het is geen transactie-systeem, maar een concurrency control. Andere methodieken zijn: timestamp controles bij update acties: dus controlleer of het record nadat de (nu gewijzigde) data gelezen is niet is gewijzigd (wie het eerst leest mag het record updaten, alle andere acties gaan verloren) of simpel overschrijf de data (wie het laatst update wint al de andere acties gaan verloren). Concurrency control is voor een groot deel een organisatorisch probleem: zorg ervoor dat niet 2 mensen hetzelfde werk gaan doen. Dat los je dus op door de applicatie af te knijpen in de initiele stap (dus de gui) wanneer een actie uberhaupt niet mogelijk is (bv A heeft 1 al in editmode, B kan dus niet 1 ook in editmode krijgen)

De reden om geen DB locks te gebruiken is in feite dat je bv uitkomt op: 'customer updaten' wat bv tot gevolg heeft dat 10 records worden gewijzigd. (het is een groot scherm, ik noem maar iets). Je kunt met die functionaliteitslogging, en dus de client dichtknijpen) veel efficienter met de materie omgaan dan recordlocks, want nu lock je dan dus 10 rows. Met functionaliteitslocking/logging geen 1.

[ Voor 58% gewijzigd door EfBe op 13-12-2002 13:28 ]

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


Verwijderd

Bij andere projecten hebben wij het ook zo gedaan, dus het locken van bepaalde records bij het starten van de edit-mode. (Dit was overigens met Delphi & Interbase).

Maar op zich vind ik het zelf wel een logische manier. Kijk als ik een bepaald record wil gaan wijzigen dan wil ik er zeker van zijn dat niemand anders aan dit record aan het editen is. Dat er hierdoor meerdere records gelockt worden (door de FK bijv) vind ik geen probleem.

En het is gewoon eenvoudig in te bouwen dat als het record te lang in edit-mode zou staan, dat het systeem dan automatisch de wijzigingen zou annuleren. (Dus om te voorkomen dat iemand anders het record nooit zou kunnen wijzigen).

Dus voor dit project (waarvan de einddatum al redelijk nadert) willen wij toch maar de "record-lock" methode gebruiken.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Je moet doen wat je niet laten kunt :) ik waarschuw je: het is de minst beste oplossing, om het even diplomatiek te formuleren ;). Je krijgt er onherroepelijk ellende mee (zoals je al ziet bij het starten van deze thread). Als je het eenvoudig wilt oplossen zou ik voor het 'overwrite-no-matter-what', gaan, dus de laatste die 'save' klikt overschrijft de data. Wanneer je recordlocking gebruikt zoals jij dat doet, kun je niet voorkomen dat iemand een functionaliteit opstart, bezig gaat en bij het saven een error krijgt, waardoor tijd verloren gegaan is. Ik zou de ontwerper een hint geven dat hij voortaan beter op moet letten en eens een docje over concurrency & database systems moet gaan doornemen :P

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


Verwijderd

Allereerst bedankt voor je reactie steeds.
EfBe schreef op 13 December 2002 @ 14:12:Ik zou de ontwerper een hint geven dat hij voortaan beter op moet letten en eens een docje over concurrency & database systems moet gaan doornemen :P
Ik ga zeker na dit project me er meer in verdiepen in de materie.
EfBe schreef op 13 December 2002 @ 14:12:Wanneer je recordlocking gebruikt zoals jij dat doet, kun je niet voorkomen dat iemand een functionaliteit opstart, bezig gaat en bij het saven een error krijgt, waardoor tijd verloren gegaan is.
Dit ben ik niet met je eens. Bij ons vorige project hebben we dit wel degelijk gerealiseerd met record locking. User A lockt record x. User B wil record x locken, maar krijgt gelijk een foutmelding dat het record door iemand anders gewijzigd wordt. Gebruiker kan dus gewoon doorgaan met het editten van record x.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Dit ben ik niet met je eens. Bij ons vorige project hebben we dit wel degelijk gerealiseerd met record locking. User A lockt record x. User B wil record x locken, maar krijgt gelijk een foutmelding dat het record door iemand anders gewijzigd wordt. Gebruiker kan dus gewoon doorgaan met het editten van record x.
Klopt, echter, het beste imho is dat B ziet in zn applicatie dat bij de actie niet kan starten en dus dat x niet gelockt wordt. Een voordeel van het semantische model, via functionaliteitlocking, is dat wanneer een ander process bv ook X nodig heeft maar alleen voor lezen, en het niet boeit of dat is geupdate of wordt geupdate, je dat door kunt laten gaan. In jouw model is dat niet zo, maar dat hoeft je nu niet op te breken natuurlijk :). Via google kom je op een aantal interessante wetenschappelijke publicaties omtrent dit fenomeen, dat door veel mensen is onderzocht. Je zult begrijpen dat er nogal wat kampen bestaan mbt dit onderwerp, de een zegt dat zijn methodiek correct is en het meest efficient, de ander uiteraard het omgekeerde. Ik ben een voorstander van de functionaliteitlocking, veelal 'semantic model' genoemd in verschillende publicaties, maar in sommige gevallen zijn andere methodieken beter. Als je een deadline in zicht hebt, is het denk ik beter om te kiezen voor de weg van de minste weerstand, alhoewel ik denk dat met wat inzet je een lowlevel concurrency scheduler snel hebt geimplementeerd en ingebed in je applicatie, zeker voor bepaalde gedeelten van de applicatie waar concurrency kan optreden.

Hier een linkje naar een MS Research document over deze materie: http://research.microsoft.com/pubs/ccontrol/

[ Voor 4% gewijzigd door EfBe op 13-12-2002 15:36 ]

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

Pagina: 1