Toon posts:

[vb/sql2000] recordlock probleempje

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik zit met het volgende probleem.
Ik ben een multiuser applicatie aan het ontwikkelen met Visual Basic 6 icm Sqlserver 2000.

Ik open een query dmv select * from blaat where blaat1 = blaat2
Dit gaat allemaal prima. Ik krijg in mij geval netjes de waardes terug die ik opvraag.

Nu wil ik dat als gebruiker1 deze query wilt openen een melding krijgt dat deze in gebruik is door een ander.

Ik heb gegoogled en got doorgespit maar kan maar weinig vinden waar ik echt wat aan heb.

Wie o wie heeft de oplossing of een voorbeeld ?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

En waarom wil je dit? :?

SQL Server biedt gewoon transactions en alles, dus dit soort primitieve mechanismes heb je niet nodig.

Professionele website nodig?


Verwijderd

Topicstarter
curry684 schreef op 12 november 2003 @ 16:56:
En waarom wil je dit? :?

SQL Server biedt gewoon transactions en alles, dus dit soort primitieve mechanismes heb je niet nodig.
Dat is helemaal fantastisch.
Ik ben nog niet zo bekend met Sql Server.
Heb je ook enig idee waar ik hier duidelijke documentatie over kan vinden ?

  • Lister
  • Registratie: September 2001
  • Laatst online: 15-02-2022
curry684 schreef op 12 november 2003 @ 16:56:
En waarom wil je dit? :?

SQL Server biedt gewoon transactions en alles, dus dit soort primitieve mechanismes heb je niet nodig.
Dat soort primitieve mechanismes heb je wel nodig als je wilt voorkomen dat je bij het updaten een melding krijgt van "Kan het record niet updaten omdat het al gewijzigd is door een andere gebruiker." of dat je update blijft hangen omdat er een recordlock is door een gebruiker die even is gaan lunchen of zoiets.

Nou weet ik niet of bromaster dat daarvoor nodig heeft maar ik heb het wel een keer nodig gehad en toen heb ik redelijk moeten zoeken om het voor elkaar te krijgen.

Het bleek dat je direct na het openen van de connectie het sql statement "SET LOCK_TIMEOUT 0" moet executen op die connectie, dan komt er gelijk een foutmelding als het record al gelocked is dat je probeert te benadere in plaats van dat hij op het afsluiten van de transactie gaat wachten.

Verwijderd

Topicstarter
Ik gebruik onderstaande code maar ik krijg geen melding en kan op beide pc's records toevoegen :S

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Set db = New ADODB.Connection
Set rsinkoop_details = New ADODB.Recordset

db.Open "Provider=MSDASQL;DSN=iets;"
rsinkoop_details.Open "select * from tbl_inkooporders_orderregels where
(tbl_inkooporders_orderregels.inkoopordernr = '" & 
frm_overzicht_bestellingen.ListView1.SelectedItem.Text & "') SET LOCK_TIMEOUT 
0", db, opendynamic, adLockOptimistic

ListView1.ListItems.Clear
ListView1.ColumnHeaders.Clear
Dim clmX As ColumnHeader
Set clmX = ListView1.ColumnHeaders.Add(, , "Id", 0)
Set clmX = ListView1.ColumnHeaders.Add(, , "Ordernr", 1000)
Set clmX = ListView1.ColumnHeaders.Add(, , "Artikelnr", 1000)
Set clmX = ListView1.ColumnHeaders.Add(, , "Omschrijving", 1000)
Set clmX = ListView1.ColumnHeaders.Add(, , "Bedrag", 1000)
Set clmX = ListView1.ColumnHeaders.Add(, , "Aantal", 1000)
Set clmX = ListView1.ColumnHeaders.Add(, , "Regeltotaal", 1000)

ListView1.View = lvwReport
ListView1.GridLines = True

While Not rsinkoop_details.EOF
Set lItem = ListView1.ListItems.Add(1, , rsinkoop_details!id)
lItem.ListSubItems.Add , , (rsinkoop_details!inkoopordernr)
lItem.ListSubItems.Add , , (rsinkoop_details!artikelnr)
lItem.ListSubItems.Add , , (rsinkoop_details!omschrijving)
lItem.ListSubItems.Add , , (rsinkoop_details!bedrag)
lItem.ListSubItems.Add , , (rsinkoop_details!aantal)
lItem.ListSubItems.Add , , (rsinkoop_details!regeltotaal)
rsinkoop_details.MoveNext
Wend
rsinkoop_details.Close
db.Close

[ Voor 12% gewijzigd door Verwijderd op 29-01-2004 14:46 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:10
Je kan in je SQL query lock hints opgeven:

bv:[code]SELECT * FROM tabel (WITH NOLOCK)[/code]

Voor meer informatie kan je misschien eens de SQL Server Books Online raadplegen. Daarnaast zijn er nog tal van websites met tal van info over Sql Server zoals SQL Team etc...


Niet goed gelezen. :+
Waarom wil je dat de andere gebruiker een melding krijgt als je gewoon waardes opvraagt, dat is toch niet nodig?
SQL Server biedt zelf al locking mechanismen.
Je kan misschien toch eens naar die LOCK HINTS kijken om te bekomen wat je wilt.

[ Voor 34% gewijzigd door whoami op 13-11-2003 08:34 ]

https://fgheysels.github.io/


Verwijderd

Verwijderd schreef op 12 november 2003 @ 20:33:
Ik gebruik onderstaande code maar ik krijg geen melding en kan op beide pc's records toevoegen :S
Als ik het goed zie voer je alleen maar een SELECT statement uit. En een SELECT statement locked niets! 2 verschillende gebruikers (wat zeg ik... wel 100 verschillende gebruikers) kunnen op exact dezelfde tijd dezelfde SELECT uitvoeren zonder dat er ook maar iets gelocked wordt. Dit is ook wel zo handig.

Als je echt de geselecteerde records wil locken moet je inderdaad met lock hints gaan werken. In SQL server weet ik het niet precies maar in Oracle gaat dat als volgt:
SELECT * FROM table WHERE a=b FOR UPDATE
Alle geselecteerd records worden nu gelocked. Je moet er echter wel voor zorgen dat ze op een bepaald moment weer vrijgegeven worden d.m.v. een Commit of Rollback anders heb je een groot probleem.

Het is echter wel een hele slechte zaak om in een multi-user omgeving onnodig veel records te gaan locken. Want wat krijg je als b.v. 1 gebruiker bepaalde informatie opvraagt (waarbij de geselecteerde records gelocked worden) en vervolgens lunchpauze neemt? Niemand kan die gegevens meer opvragen!!! Ik denk dat je multi-user applicatie op deze manier zeer snel onbruikbaar gaat worden zodra er meer dan 1 gebruiker mee gaat werken >:).

Ik raad je aan oms eens te gaan zoeken naar de termen "Pessimistic concurrency" , "Optimistic concurrency" en "Last in wins". Jij zoekt je oplossing in pessimistic concurrency control terwijl voor een multi-user applicatie optimistic concurrency control veel beter is.

edit:
Even een linkje opgezocht: Introduction to Data Concurrency in ADO.NET

[ Voor 34% gewijzigd door Verwijderd op 13-11-2003 09:22 . Reden: types en uitleg uitgebreid ]


Verwijderd

Topicstarter
Als gebruiker 1 de bovenstaande code uitvoert mag een ander er niets aan veranderen. Het zijn namelijk inkooporderregels die op dat moment gewijzigd / bijgevoegd worden.
Met deze code zou het dus moeten werken ?
code:
1
2
3
4
rsinkoop_details.Open "select * from tbl_inkooporders_orderregels where
(tbl_inkooporders_orderregels.inkoopordernr = '" & 
frm_overzicht_bestellingen.ListView1.SelectedItem.Text & "'for update)", db, 
opendynamic, adLockOptimistic

Ga vanavond weer snel verder.

[ Voor 6% gewijzigd door Verwijderd op 13-11-2003 09:21 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:10
FOR UPDATE is Oracle specifiek, en zal niet echt werken in Sql server geloof ik.
Kijk eens in de books online naar de verschillende locking hints.

https://fgheysels.github.io/


Verwijderd

Topicstarter
Bedankt voor de reacties.
Ik heb het ondertussen maar opgelost door bij het openen van het record de waarde 1 in een tabel te schrijven en bij het sluiten van het record weer op 0 te zetten.
Ik zal er eens een boek van sql op naslaan maar voorlopig werkt het even zo
Pagina: 1