|  | 		    
					
        
         
          
         
	
          | |  | Generelt om samtidighed Fra : Jens R. Rasmussen
 | 
 Dato :  08-11-09 16:45
 | 
 |  | 
 
            hej/
 Jeg roder lidt rundt i ADO. Jeg kan oprette en connection og jeg
 kan oprette et recordset. Men jeg har endnu ikke rigtigt forstået
 hvordan man klarer situationen, når 2 brugere samtidig tilgår den
 samme record i min access database.
 Jeg vil gerne - fra min administratorside - tilgå Kundetabellen
 og ændre fx kunden (Hans Peter) med id = 17.
 Mine kunder har adgang til samme database og kan opdatere deres
 deres egne data, så jeg risikerer at Hans Peter er inden i samme
 tabel mens jeg vil tilgå den.
 Mit ønske er
 - at jeg venter til pågældende record ikke er optaget mere (dvs.
 Hans Peter har forladt den)
 - at mens jeg er inde og rette i hans Peters data, må ingen andre
 få adgang.
 Tidligere har Stig fortalt lidt om BeginTrans uden at jeg
 desværre rigtigt forstår hvad jeg skal gøre. Findes der ikke en
 lock unlock kommando eller lignende som man bruger når flere
 samtidig kan risikere at tilgå samme tabel eller samme record?
 Jeg har læst på w3schools.com - desværre uden rigtigt at løse mit
 problem. 
 Kan nogen kort fortælle mig om samtidighedsproblemer - eller
 henvise til en side om samme?
 mvh
     /Jens
 -- 
 Vil du lære at kode HTML, XHTML, CSS, SSI, ASP eller ASP.NET?
  - Pædagogiske tutorials på dansk
  - Kom godt i gang med koderne
 KLIK HER! => http://www.html.dk/tutorials |  |  | 
  Leif Neland (08-11-2009) 
 
	
          | |  | Kommentar Fra : Leif Neland
 | 
 Dato :  08-11-09 17:35
 | 
 |  | Jens R. Rasmussen skrev:
 > hej/
 >
 > Jeg roder lidt rundt i ADO. Jeg kan oprette en connection og jeg
 > kan oprette et recordset. Men jeg har endnu ikke rigtigt forstået
 > hvordan man klarer situationen, når 2 brugere samtidig tilgår den
 > samme record i min access database.
 >
 > Jeg vil gerne - fra min administratorside - tilgå Kundetabellen
 > og ændre fx kunden (Hans Peter) med id = 17.
 >
 > Mine kunder har adgang til samme database og kan opdatere deres
 > deres egne data, så jeg risikerer at Hans Peter er inden i samme
 > tabel mens jeg vil tilgå den.
 >
 > Mit ønske er
 > - at jeg venter til pågældende record ikke er optaget mere (dvs.
 > Hans Peter har forladt den)
 > - at mens jeg er inde og rette i hans Peters data, må ingen andre
 > få adgang.
 >
 
 Problemet med at redigere samme record flere steder fra kan ikke løses
 (umiddelbart) i html.
 
 Sagen er, at når bruger A har hentet recorden, og får den vist på
 skærmen, så er der ikke forbindelse til serveren mere.
 
 Så bruger B kan hente recorden, og redigere den også.
 
 A gemmer den, derefter gemmer B, og overskriver derfor A's rettelser.
 
 Du kan sætte et flag, når A henter, så det er markeret, at ingen andre
 må lave rettelser, men hvad hvis A forlader pc'en, og går til frokost,
 og får en tagsten i hovedet?
 
 Man kan så lave en admin-adgang til at låse op.
 
 En metode, jeg har set, er at der til hver record er et felt, der
 indeholder opdateringstidspunkt.
 
 Dette felt er en del af nøglen til tabellen.
 
 Når man så vil gemme, angiver man at man vil gemme den record med f.ex.
 cprnr 1234567890, med opdateringstidspunkt 1.nov.2009 16:12:24
 Er recorden blevet opdateret i mellemtiden, findes den record ikke mere,
 og man får en fejlmeddelelse. Så får man vist recorden med de data, den
 anden bruger har lavet, og man må skrive sine rettelser igen.
 
 Men man må så lave databasen og sine procedurer således, at det ikke er
 sansynligt at to retter i de samme data.
 
 Leif
 
 
 |  |  | 
  Stig Johansen (08-11-2009) 
 
	
          | |  | Kommentar Fra : Stig Johansen
 | 
 Dato :  08-11-09 18:26
 | 
 |  | Leif Neland wrote:
 
 > En metode, jeg har set, er at der til hver record er et felt, der
 > indeholder opdateringstidspunkt.
 
 Den er lidt farlig, den med tidspunktet.
 
 Man risikerer at få afrundingsgejl, da det ræpresenteres (internt) med
 floating point.
 
 Jeg har selv brug fortløbende tællere(versionsnummer) på recorden, og så kan
 man puute de tidligere versioner i et historik datasæt, så men se tidligere
 versioner.
 
 @Jens
 Det med begintrans og commit/roolback er når der skal opdateres flere
 sammenhængende data.
 
 Hvis man f.eks. har en konto med en saldo, og et datasæt med posteringer, så
 skal begge (eller ingen) opdateres.
 
 det gøres med:
 begintrans
 opdater saldo
 put posteringer
 commit
 
 Den problemstilling du er inde på gar været diskuteret i umindelighed (for
 mit vedkommende 25+ år), og der findes ikke nogen brugbar 'løsning'.
 
 Jeg har set systemer hvor data bliver 'låst' under rettelse, med det gør
 større skade end gavn.
 
 Stor panik fra det ene kontor: 'Hvem helvede har låst xyz?'.
 
 Det dur ikke med låsninger i andet end split sekunder i større systemer.
 
 Jeg har fra tidernes morgen anlagt den pragmatisk holdning at:
 1) Sandsynligheden for at to personer retter f.eks. en adresse samtidig, er
 forhåbentlig = 0, for ellers er der noget galt med forretningsgangen.
 
 2) Hvis det endelig sker, så har 'sidste' mand lige så meget ret, som den
 'første'.
 
 --
 Med venlig hilsen
 Stig Johansen
 
 
 |  |  | 
   Rune Jensen (08-11-2009) 
 
	
          | |  | Kommentar Fra : Rune Jensen
 | 
 Dato :  08-11-09 20:31
 | 
 |  | Stig Johansen skrev:
 
 > Stor panik fra det ene kontor: 'Hvem helvede har låst xyz?'.
 
 "Hvem hulen har låst Oracle???"
 
 plejer at være det gængse her... Og så følger enten mail eller
 'fonopringing til den formastelige. Mest irriterende, hvis vedkommende
 er gået til frokost med åbent "view".
 
 ;)
 
 Men okay, SÅ tit sker det nu heller ikke, så det er trods alt til at
 leve med. Det er iøvrigt det samme andre steder, jeg har været.
 
 
 
 MVH
 Rune Jensen
 
 
 |  |  | 
    Jens R. Rasmussen (08-11-2009) 
 
	
          | |  | Kommentar Fra : Jens R. Rasmussen
 | 
 Dato :  08-11-09 23:15
 | 
 |  | 
 
            Rune Jensen wrote in dk.edb.internet.webdesign.serverside.asp:
 > Stig Johansen skrev: 
 >  
 > > Stor panik fra det ene kontor: 'Hvem helvede har låst xyz?'. 
 >  
 > "Hvem hulen har låst Oracle???" 
 >  
 > plejer at være det gængse her... Og så følger enten mail eller  
 > 'fonopringing til den formastelige. Mest irriterende, hvis vedkommende  
 > er gået til frokost med åbent "view". 
 >  
 > ;) 
 >  
 > Men okay, SÅ tit sker det nu heller ikke, så det er trods alt til at  
 > leve med. Det er iøvrigt det samme andre steder, jeg har været. 
 >  
 >  
 >  
 > MVH 
 > Rune Jensen
 Tak alle 3 - jeg er enig i, at sandsynligheden for samtidighed er lille og
 at hvis det skulle ske, så har 'B' ligeså meget ret som 'A' - så i værste
 fald må 'A' lige tjekke en ekstra gang efter opdatering for at se om hans
 opdatering er slået igennem.
 Men Runes sidste bemærkning tyder på, at man kan låse - selv om det kan
 skabe ballade fra andre. Nu ønsker jeg, at det kun er mig fra min
 administratorside, der kan låse - andre kan ikke. Så jeg er selv herre
 over hvorlænge der er låst - med mindre tagstenen falder ned    Men konkret - hvordan låser man en record og hvordan låser man den op
 igen? Hvis mit recordset hedder rs, er der så en rs.lock og en rs.unlock ?
 Eller er det på connection-niveau der skal låses?
 mvh   /jens
 -- 
 Vil du lære at kode HTML, XHTML, CSS, SSI, ASP eller ASP.NET?
  - Pædagogiske tutorials på dansk
  - Kom godt i gang med koderne
 KLIK HER! => http://www.html.dk/tutorials |  |  | 
     Stig Johansen (09-11-2009) 
 
	
          | |  | Kommentar Fra : Stig Johansen
 | 
 Dato :  09-11-09 06:27
 | 
 |  | 
 
            Jens R. Rasmussen wrote:
 > Rune Jensen wrote in dk.edb.internet.webdesign.serverside.asp:
 >>  
 >> "Hvem hulen har låst Oracle???"
 >>  
 >> plejer at være det gængse her... Og så følger enten mail eller
 >> 'fonopringing til den formastelige. Mest irriterende, hvis vedkommende
 >> er gået til frokost med åbent "view".
 Det var netop det, der skete i de tilfælde jeg snakkede om.
 > Men Runes sidste bemærkning tyder på, at man kan låse - selv om det kan
 > skabe ballade fra andre. 
 Den slags systemer vi snakker om er statefull systemer, altså hvor man har
 en konstant forbindelse til systemet.
 På den slags systemer kan man godt indføre låsemekanismer, da men altid
 kører i 'samme program', og dermed kan styre låsninger.
 Låsningsfaciliter er i øvrigt afhængig af databasen.
 Nogle kører kun med table locking, eller page locking, så der får man låst
 mere end man ønsker.
 Når man snakker web og HTTP, så er det stateless, så for hvert billede, så
 kalder klienten serveren op, og beder om ngle ting, derefter svarer
 serveren, og 'lægger røret på'.
 Der er med andre ord ingen sammenhæng mellem requests, så en eventuel
 låsning i 'hent data' vil ikke blive båret videre til 'ret data' osv.
 Du må finde andre metoder til at styre det.
 Du kunne lægge et flag på din tabel, eks. islocked, og lave noget kode a la:
 En rette funktion:
 if request.method=get then
    SQL = "update kunde set islocked=1 where kunde=? and islocked=0"
    if rowsaffected = 0 then
       response.write "kunde findes ikke eller er låst"
      afslut
    end if
    SQL = "select data from kunde where kundenr=?"
   osv..
 end if
 if request.method=post then
    update kunde set data=...osv, islocked=0 where kundenr? and islocked=1
    if rowsaffected = 0 then
      write "kunde kunne ikke opdateres, eksisterer ikke elller er låst"
    end if
 > Nu ønsker jeg, at det kun er mig fra min 
 > administratorside, der kan låse - andre kan ikke. Så jeg er selv herre
 > over hvorlænge der er låst - med mindre tagstenen falder ned    Det nytter ikke noget at du kan låse hvis andre ikke kan, for så virker det
 ikke.
 I forhold til ovenstående, kan du evt. bruge 0 eller timestamp for låsning,
 så kan du sætte et online cron job op, der fjerner løsninger, der er 'for
 gamle'.
 eks.
 update kunde set islocked=0 where islocked < now - 0,042
 0,042 er ca. 1 time.
 > Men konkret - hvordan låser man en record og hvordan låser man den op
 > igen? Hvis mit recordset hedder rs, er der så en rs.lock og en rs.unlock ?
 > Eller er det på connection-niveau der skal låses?
 Slå det ud af tankerne, det kan ikke lade sig gøre i HTTP.
 -- 
 Med venlig hilsen
 Stig Johansen
            
             |  |  | 
      Jens R. Rasmussen (09-11-2009) 
 
	
          | |  | Kommentar Fra : Jens R. Rasmussen
 | 
 Dato :  09-11-09 21:23
 | 
 |  | 
 > Slå det ud af tankerne, det kan ikke lade sig gøre i HTTP. 
 >  
 > --  
 > Med venlig hilsen 
 > Stig Johansen
 Ok - det er glemt    Min løsning er herefter (måske lidt klodset, men jeg kunne ikke få
 rename(gammeltnavn, nytnavn) til at virke:
 1) jeg har en asp-side (ved navn erstatningssideaktiv.asp - som forklarer at
 brugeren desværre pt. ikke har adgang til databasen.
 2) Hver gang jeg skal give en bruger adgang til databasen tjekker jeg om der i
 mit directory findes en fil ved navn erstatningssideaktiv, og hvis "ja" får han
 adgang til denne istedet for til at kunne redigere i databasen, dvs.
 folderspec = server.Mappath("/")
 Set fso = CreateObject("Scripting.FileSystemObject")
 Set f = fso.GetFolder(folderspec)
 Set fc = f.Files
 For Each f1 in fc
 If f1.name = "erstatningssideaktiv.asp" Then
 Server.Transfer ("erstatningssideaktiv.asp")
 Else
 End if    
 Next
 3) filen ligger normalt under navnet "erstatningsideINaktiv.asp" og gør således
 ingen "skade".
 4) Når jeg selv vil ændre i database uden samtidighedsproblemer starter jeg på
 min kodeordbeskytrtede administratorside med 
 For Each f1 in fc
 If f1.name = "erstatningssideINaktiv.asp" Then
 f1.name = "erstatningssideaktiv.asp"
 Else
 End if    
 Next
 5) skynder jeg mig så at lave mine ændringer på administratorsiden, undgår
 tagsten og sluttes af med den modsatte dvs.
 For Each f1 in fc
 If f1.name = "erstatningssideaktiv.asp" Then
 f1.name = "erstatningssideINaktiv.asp"
 Else
 End if    
 Next
 6) og så har alle andre igen adgang til at kunne tilgå databasen, da
 ertsatningssiden nu er inaktiv.
 Nok lidt kluntet - men jeg tror det vil virke.
 Tak for hjælpen, og at I bremsede mig med mine fikse ideer om lock/unlockning
 af records og connections. Men så blev jeg så klog    mvh
     /jens
 -- 
 Vil du lære at kode HTML, XHTML, CSS, SSI, ASP eller ASP.NET?
  - Pædagogiske tutorials på dansk
  - Kom godt i gang med koderne
 KLIK HER! => http://www.html.dk/tutorials |  |  | 
       Stig Johansen (10-11-2009) 
 
	
          | |  | Kommentar Fra : Stig Johansen
 | 
 Dato :  10-11-09 03:29
 | 
 |  | Jens R. Rasmussen wrote:
 
 > Min løsning er herefter (måske lidt klodset, men jeg kunne ikke få
 > rename(gammeltnavn, nytnavn) til at virke:
 
 Ja, det virker bøvlet (og klodset).
 
 Prøv at kigge på det løsningsforslag jeg gav, og brug 0 eller now til at
 anføre låsning.
 
 Det vil virke altid, i forhold til samtidighedsproblemer, og kombineret med
 en online cron job, løser det også dit 'tagstensproblem'.
 
 Ok, hvis du sætter cronjobbet til at slette låsninger efteer f.eks. ½ time,
 så vil det betyde, at man skal have rettet færdigt inden denne ½ time.
 
 Derudover kan du lave en 'fjern låsninger' side.
 
 --
 Med venlig hilsen
 Stig Johansen
 
 
 |  |  | 
  Stig Johansen (09-11-2009) 
 
	
          | |  | Kommentar Fra : Stig Johansen
 | 
 Dato :  09-11-09 08:06
 | 
 |  | 
 
            "Jens R. Rasmussen" <Jens.R.Rasmussen@rasmussen.dk> wrote in message
 news:4af6e775$0$277$14726298@news.sunsite.dk...
 >
 > Tidligere har Stig fortalt lidt om BeginTrans uden at jeg
 > desværre rigtigt forstår hvad jeg skal gøre.
 Nu er det ikke et svar på dit spørgsmål, men jeg kom i tanke om, at jeg har
 et dugfrisk eksempel på begintrans m.v.
 Jeg leger lidt med et bud på hvordan man kan lave et (ASP drevet) galleri:
http://w-o-p-r.dk/gallery/ (Kun et hobby projekt, men koden bliver tilgængelig for alle).
 I den forbindelse er det nødvenfidt at indføre en bekræftelsesmail, eller
 aktiveringmail, for at forhindre misbrug.
 Endvidere må man ikke kunne oprette samme bruger id 2 gange.
 Så problemstillinger er, at enten bliver brugeren oprettet *og* mail
 afsendt, eller *intet*.
 Her er et uddrag af koden, hvor jeg bruger begintrans m.v.
    oConn.Begintrans ' her starter transaktionen
    Rowsaffected = Query(oConn,SQL,Parameters,4)
    if Rowsaffected = 1 then
       Set msg = Server.CreateObject("JMail.Message")
 .....
       if not msg.Send("smtp.unoeuro.com") then
         oConn.RollbackTrans ' afsendelse fejlet, undlad oprettelse
       Else
         oConn.CommitTrans ' oprettelse samt afsendelse ok, gem ændringer
       end if
    else ' sikkert duplicate
       oConn.RollbackTrans ' oprettelse fejlet, afslut transktionen
    end if
 .....
 Som du kan se, så bruger man det til at sikre at flere hændelser enten alle
 bliver udført, eller ingen udført.
 --
 Med venlig hilsen/Best regards
 Stig Johansen
            
             |  |  | 
 |  |