Hej Hej Det är tyvärr så att det är olöst... Inte bara för dig. Hej För att låsa/låsa upp posten kan du använda transaktioner. ADO har stöd för detta. I proceduren som uppdaterar kan du alltså: Jag brukar göra enligt följande Transaktioner verkar vara lösningen för mig, jag skall testa det i helgen när jag har lite bättre I min variant där man tar med fälten vid urvalet vid update finns det väl ingen risk att de skriver samtidigt ? I enkla fall kan jag hålla med om att din variant av update är överlägsen. JoHur låser man en post med ADO?
Jag läser in en posts alla fält till ett formulär och stänger connection precis som jag
lärt mig att man skall. Sen skall Nisse kunna ändra på något värde och spara.
Detta är klart och det funkar.
Men... i ett fleranvändarsystem så kan Stina ha sökt upp samma post gjort ändringar
och sparat innan Nisse får tummen ur och hinner spara sina ändringar.
Precis när Nisse sparar sina ändringar vill jag kunna
10 låsa posten (så att Stina inte kan spara sina ändringar)
20 kolla att datat som läste in i formen från början stämmer med datat på posten
30 om datat är ändrat så meddela Nisse att posten är ändrad av Stina
40 om datat inte är ändrat så spara ändringarna
50 låsa upp posten.
Frågan är: Hur låser jag en post med ADO?
Följdfråga: Hur låser jag upp den?
Jag kör mot en Access 2000 databas och MDAC 2.8
Vet inte om det behövs men jag slänger in lite kod också.
Så här hämtar jag posten:
<code>
Private Sub Command1_Click()
gswInitADO
Set rst = Con.Execute _
("select * from Suppliers where Number = '3'")
Text1.Text = rst("Number")
Text2.Text = rst("Name")
Text3.Text = rst("CurrencyID")
rst.MoveNext
gswClearADO
End Sub
</code>
Spara posten:
<code>
Private Sub Command4_Click()
Dim mySQL
gswInitADO
If Text1.Text <> "" Then
mySQL = "Update Suppliers Set Name = '" & Text2.Text & "', CurrencyID = " & Text3.Text & " Where Number = '" & Text1.Text & "'"
Con.Execute mySQL
Else
MsgBox "Det finns ingen leverantör i formuläret.", vbInformation + vbOKOnly, "Spara ändringar på leverantör"
End If
gswClearADO
End Sub
</code>
Så här ser min connectionsträng ut:
<code>
Public Sub gswInitADO()
Dim ConnectionString As String
Set Con = New ADODB.Connection
Set rst = New ADODB.Recordset
ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Test\test.mdb;Persist Security Info=False"
On Local Error Resume Next
Con.Open ConnectionString
If Con.Errors.Count > 0 Then
MsgBox "Anslutningen misslyckades!" & vbCrLf & Con.Errors(0).Description
End If
End Sub
</code>
Mvh/OlofSv: Hur låser man en post med ADO?
Gammalt problem men tyvärr fortfarande olöst.
Finns det någon vänlig själ som kan hjälpa mig?
Ställ motfrågor om jag varit otydlig.
Mvh/OlofSv: Hur låser man en post med ADO?
Du kan använda ett kontinuerligt öppet recordset och köra rs.update på det. Då får du kontrollerna du önskar, men också en connection som ligger kvar längre än du (troligtvis) önskar.
Annars får du köra om din select precis innan din update för att kolla att posten finns kvar.
/mickeSv: Hur låser man en post med ADO?
Räcker det inte så här ?
Ta med alla (Name, CurrensyID) fält i urvalet vid update.
Kolla med RecordsAffected om någon anna hunnit före
/JohanSv: Hur låser man en post med ADO?
1 BeginTransaction
2 Göra en samma select som innan och jämföra värdena
3 Om värdena är ändrade: RollbackTransaction och meddela användaren
4 Annars: uppdatera posten och CommitTransaction
Det är att rekommendera att istället göra allt detta inifrån en lagrad procedur, men jag vet inte om Access 2000 har stöd för lagrade procedurer.
Lycka till!
/PelleSv: Hur låser man en post med ADO?
varje post har ett timestamp från när den sparade sist
när man läser upp en post till formuläret lagrar man timestampvärdet i en variabel
nar ma skrivet tillbaka posten kollar man om värdet i denna variabel är det samma som i tabellen
är det samma vet man att ingen annan har ändrat under tiden, är det inte samma så har någon annan
ändrat posten under tiden.
Har någon ändrat posten under tiden läser man upp posten till formuläret igen och användaren får göra om sin ändring
Annars tror jag att man via ado kan sätta typ av concurrency
och väljer man pessimistic så skall man inte kunna ändra poster samtidigt
men jag är inte säker...
Men en sak är jag säker på
Access har inte stöd för lagrade procedurer på samma sätt som typ sql-server
men man kan ju skriva vba-kod som via ADO kör sql-satser.Sv: Hur låser man en post med ADO?
med tid.
Att göra en kontroll (oavsett om man kollar alla fält på posten eller använder timestamp) och
sen sparar om inget ändrats har ju en liten fördröjning inbyggd. I ett långsamt nätverk eller
med en klen server så finns det vad jag förstår en teoretisk möjlighet att två användare som
sparar samtidigt ”lyckas” med att spara men en användares ändringar sparas ju över
omgående. Det är risken förknippad med den här lilla fördröjningen som jag vill eliminera.
Tack alla.
Mvh/OlofSv: Hur låser man en post med ADO?
Min erfarenhet (kanske begränsad) säger att låsningar leder till problem och ska användas i nödfall.
/JohanSv: Hur låser man en post med ADO?
Låsningar görs alltid vid uppdateringar. Jag antar att det du menar är deadlock-problem. Sådana problem riskerar man endast om man gör uppdateringar på flera ställen i samma transaktion.
/PelleSv: Hur låser man en post med ADO?
I det här fallet verkar det i alla fall helt onödigt med låsning.
/Johan