[VB6/MSSQL] Concurrency probleem

Pagina: 1
Acties:

  • BestTested!
  • Registratie: Oktober 2003
  • Laatst online: 23-05 20:37
Een tijd geleden heb ik een programma geschreven in VB6.0 voor bedrijfsadministratie werkzaamheden. Dat programma zou toen door slechts 1 gebruiker tegelijk worden gebruikt.
Nu is dat bedrijf flink aan het groeien, en komt het regelmatig voor dat er 2 mensen tegelijk nodig zijn. Ik heb hier bij het ontwerp van mijn programma toen helaas geen rekening mee gehouden.

Ik ben nu wat aan het rondsnuffelen geweest over concurrency en locking, maar ik kom er zelf niet helemaal uit. Daarom, geachte tweakers, zou ik graag jullie advies willen hebben.


Technische specificaties:

Taal: VB6.0
DBMS: MS SQL Server 2000

In het programma worden steeds connecties aangemaakt via ADO (geen adodc). De recordsets worden aangemaakt en nadat alle data verstuurd/ontvangen is wordt de connectie weer verbroken.

De DBMS staat op een apparte server, de applicatie draait op fat-clients. De clients kennen elkaar onderling niet (laptops van de gebruikers zelf).

Het komt niet echt vaak voor dat de twee gebruikers dezelfde records aan het editten zijn, maar ik moet er absoluut zeker van zijn dat dit niet mogelijk is. (Murphy >:))
Wat dus niet mag gebeuren is: Gebruiker A haalt data op, gebruiker B haalt dezelfde op, B veranderd en update de data, A veranderd en update de data waardoor de wijzigingen die B aanbracht weer weg zijn.
Wat wel kan ik dat gebruiker A dan een message ziet, dat de velden veranderd zijn, en of hij zeker weet dat hij de updates wilt doorvoeren. (De gebruikers zitten bijna altijd bij elkaar)
Dit moet natuurlijk niet gelden wanneer er andere records worden aangevraagd uit dezelfde tabel of wanneer er slechts data wordt aangevraagd die niet geupdate hoeft te worden (die velden kan ik dan wel in VB locken, zodat ze niet ge-edit kunnen worden), dus eigenlijk 'read-only' records.

Oplossingen:
Optimistic Locking
Pessimitic Locking
Cursor Locking - Read Only
Cursor Locking - Optimistic With Values
Cursor Locking - Optimistic With Row Versioning
Cursor Locking - Scroll Locks

Graag had ik julli (onderbouwde) advies over welke manier van locking toe te passen op dit probleem. En over hoe dit te integreren in het huidige programma.

Bij Voorbaat dank!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:52
Pessimistic locking is meestal geen goed idee, imo zeker niet voor administratie-appjes. Stel dat een lock nooit vrijgegeven wordt.

Het beste is dus om uit te gaan van optimistic locking. Je kan aan iedere tabel een extra veld toevoegen (of 2 extra velden) met de datum waarop het record laatst gewijzigd werd (timestamp).
Bij het aanpassen van de gegevens ga je dan kijken of de timestamp die jij had opgehaald nog overeenkomt met de timestamp van het record. Indien dit het geval is, ga je de update doorvoeren, indien dit niet het geval is, ga je niets aanpassen en een melding tonen aan de gebruiker dat het record gewijzigd is.
Die gebruiker zal dan het record opnieuw moeten ophalen en z'n data opnieuw eventueel opnieuw aanpassen.

https://fgheysels.github.io/


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Voeg gewoon een middle-tier in? :?

Professionele website nodig?


  • BestTested!
  • Registratie: Oktober 2003
  • Laatst online: 23-05 20:37
Even ter controle. Zoiets dus...
OPTIMISTIC WITH ROW VERSIONING

This optimistic concurrency control option is based on row versioning. With row versioning, the underlying table must have a version identifier of some type that the server can use to determine whether the row has been changed after it was read into the cursor.
Natuurlijk is dit vrij eenvoudig zelf te programmeren, maar zit zoiets al niet ingebouwd in MSSQL2000?

De volgende 3 bronnen komen van MSDN
In SQL Server, that capability is provided by the timestamp data type, which is a binary number that indicates the relative sequence of modifications in a database. Each database has a global current timestamp value, @@DBTS. Each time a row with a timestamp column is modified in any way, SQL Server stores the current @@DBTS value in the timestamp column and then increments @@DBTS. If a table has a timestamp column, then the timestamps are taken down to the row level. The server can then compare the current timestamp value of a row with the timestamp value that was stored when the row was last fetched to determine whether the row has been updated. The server does not have to compare the values in all columns, only the timestamp column. If an application requests optimistic concurrency with row versioning on a table that does not have a timestamp column, the cursor defaults to values-based optimistic concurrency control.

Transact-SQL cursors
Specify the READ_ONLY, SCROLL_LOCK, and OPTIMISTIC keywords on the DECLARE CURSOR statement. The OPTIMISTIC keyword specifies optimistic with row versioning, Transact-SQL cursors do not support the optimistic with values concurrency option.

ADO applications
Specify adLockReadOnly, adLockPessimistic, adLockOptimistic, or adLockBatchOptimistic in the LockType property of a Recordset object.
Dus als ik bij mijn recordset adLockOptmimistic als LockType property opgeef, dan ik dit in feite gerealiseerd? Met (fout)melding en alles? Of moet ik dat dan alsnog zelf programmeren?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

BestTested! schreef op 05 juli 2004 @ 16:37:
Even ter controle. Zoiets dus...

[...]


Natuurlijk is dit vrij eenvoudig zelf te programmeren, maar zit zoiets al niet ingebouwd in MSSQL2000?
Sterker nog, er is zelfs een 'rowversion' datatype geintroduceerd in SQL2k als preferred alias voor 'timestamp' :) Dit is omdat op termijn 'timestamp' gaat vervallen omdat de huidige SQLServer implementatie niet aan SQL-92 conformeert :Y)

Professionele website nodig?


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:52
BestTested! schreef op 05 juli 2004 @ 16:37:
Even ter controle. Zoiets dus...

[...]


Natuurlijk is dit vrij eenvoudig zelf te programmeren, maar zit zoiets al niet ingebouwd in MSSQL2000?
Zoals ik reeds gezegd heb: een timestamp column, en een UPDATE statement dat je als volgt schrijft:

code:
1
2
3
4
UPDATE tabel
SET ...
WHERE tabel.id = <selectedPK>
AND tabel.datum_mod = <datummodrecord>

https://fgheysels.github.io/


  • BestTested!
  • Registratie: Oktober 2003
  • Laatst online: 23-05 20:37
Thx allemaal. Mijn inzichten over concurrency zijn een hoop duidelijk geworden. Ik ga maar eens lekker verder proggen. Soms zie je door de bomen het bos niet meer. Ik kom er voor de rest wel uit.
Pagina: 1