Avatar billede hrc Mester
09. februar 2018 - 14:45 Der er 8 kommentarer og
1 løsning

Kan SPID skifte over en ADOCOnnection?

Jeg har en base hvor SPID'et bliver brugt til at identificere brugerne i et Win32 baseret system.

Når der bliver åbnet en ADO-forbindelse til basen, genererer SQLServeren et SPID. Brugerens ID forbindes med denne, ved at indsætte en record i tabellen loginpool (id,spid,oprettet). Eks. (202,50,"20180209")
Næsten alle steder i basen, refereres der til brugeren via en funktion (GetBrugerID()) der blot laver en "select id from dbo.loginpool where spid=@@spid".Hvis @@spid er 50, så vil funktionen returnere ID 202 i ovenstående eksempel.
Logud-proceduren er simpel, idet man blot sletter en record "delete from dbo.loginpool where spid=@@spid"

Nu oplever jeg at GetBrugerID kan returnere NULL. Det betyder enten at recorden ikke findes længere, eller at SPID er skiftet fordi forbindelsen var røget, men automatisk genoprettet med et nye SPID. Kan ADO kan finde på sådan noget?
Avatar billede Syska Mester
09. februar 2018 - 15:05 #1
Ja,

http://sqlserverplanet.com/dba/spid-what-is-it

Se dit som et Process Id i Windows eller Linux ... det kan ændre sig hele tiden ... så du har ingen garanti for noget som helst ...

Men ... hvordan sikre du dig også at de logger ud? Reelt kunne du jo bare lukke programmet og jeg ville måske få dit process id ...

Så ... bottom line ... don't do this.
Avatar billede hrc Mester
09. februar 2018 - 15:22 #2
Fejlen kan måske ligge et andet sted. Når en bruger logger ind, så rydder jeg op i eventuelle "døde" logins.

  delete from dbo.loginpool
  where (spid not in (select distinct sp.spid
                      from sys.sysprocesses sp
                      join sys.sysdatabases sd on (sd.dbid = sp.dbid)
                      where (sd.dbid = DB_ID())))

Så melder tanken sig. Hvad styrer DB_ID()? Hvis DB_ID ikke er den base jeg kigger i, så vil den rydde basen.
Avatar billede arne_v Ekspert
09. februar 2018 - 15:23 #3
Taler vi ADO i VBS, C++ eller Delphi? Eller ADO.NET i C#?
Avatar billede arne_v Ekspert
09. februar 2018 - 15:27 #4
@#1

Linket siger:


A SPID in SQL Server is a Server Process ID. These process ID’s are essentially sessions in SQL Server. Everytime an application connects to SQL Server, a new connection (or SPID) is created.


saa det burde faktisk virke ved:
* connect
* indsaet i bruger tabel
* lav X handlinger som kalder funktion
uanset logud haandtering eller ej.

Min bedste hypotese er at der sker en automatisk reconnect under applikations niveau.
Avatar billede hrc Mester
09. februar 2018 - 15:29 #5
syska: Men et SPID er unikt for en session. Det er definitionen, så den eneste fejlmulighed jeg kan komme på er, hvis forbindelsen til basen kortvarig mistes og genoprettes med et nyt SPID ... men så er det ikke samme session, det er et nyt. Jeg tror ikke på det er muligt.

Mht. logge ud. Hvis programmet dør (husk det er et Win32), så er der et dødt login i loginpool-tabellen, men hvis brugerne lukker normalt, så sletter jeg jo bare recorden.

Hvis mit post #2 er grunden til mine kvaler, så holder konceptet altså vand - hvilket det har gjort i de 10 år programmet har eksisteret; det er ikke en dum idé. Der er mange fordele. Med den seneste justering, introducerede jeg en grundlæggende ændring i basen og så opstod der problemer. Jeg hælder meget til at det er oprydningsrutinen der kvajer sig, fordi DB_ID returnerer forkert ID.
Avatar billede arne_v Ekspert
09. februar 2018 - 17:29 #6
delete from dbo.loginpool
  where (spid not in (select distinct sp.spid
                      from sys.sysprocesses sp
                      join sys.sysdatabases sd on (sd.dbid = sp.dbid)
                      where (sd.dbid = DB_ID())))

giver ingen mening for mig.

slet record for sessions som (ikke er i (aabne sessions i en bestemt database))

maaske de mente:

slet record for sessions som (ikke er i (aabne sessions) og er i (en bestemt database))

??
Avatar billede arne_v Ekspert
09. februar 2018 - 17:30 #7
og hvorfor bruger man ikke datoen naar den nu indsaettes??
Avatar billede hrc Mester
12. februar 2018 - 11:43 #8
Arne: Sletningen i loginpool er et forsøg på at slippe af med hængende login'er. Altså de hvor programmet ikke er lykkes logge ud. Jeg prøver at ramme de situationer hvor programmet er gået ned.

Tesen var: Hent liste over de SPID som har "connection" til databasen. Slet, i dbo.loginpool, alle de records som ikke har et SPID i denne liste.

... men det lader til DB_ID driver gæk med mig. Umiddelbart virker det i mit testmiljø, men hos kunden tror jeg den returnerer et forkert ID resulterende, at når en bruger logger ind, så logger den alle andre ud! Kaldet er udkommenteret og de har (tilsyneladende) kørt problemfrit siden.
Avatar billede hrc Mester
09. november 2018 - 12:30 #9
Jeg er kommet noget videre med denne løsning, men også stødt på meget IT-modstand. Hvis man, med almindelige rettigheder for et login, henter oplysninger i SysProcesses, så finder man kun ens egen SPID. Det er derfor nødvendigt at grante login med "View srver state". Her stejler mange IT-afdelinger for alle steder det er beskrevet, er der en fraskrivelse af ansvar, med henvisning på risikoen for en hacker kan misbruge oplysningerne her. Ingen vil lægge hovedet på blokken og sige, at det her er ret ufarligt, så derfor håndteres det som en reel bagdør. Fandens til bøvl at overtale dem til at sætte den "grant".

Selve fejlen med at der blev returneret NULL, ser ud til at være fikset. Det var en lidt for grundig indledende oprydning ved login.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester