Ressources lock bloquées par d'autres processus [SQL Server] - SQL/NoSQL - Programmation
Marsh Posté le 14-01-2004 à 17:44:39
t'es pas un peu goret toi ?
vire-moi ces delete de partout !
crée un trigger "on insert" sur ta table, qui fait un insert ou un update selon les cas.
et pour shooter les vieilles cnx inutilisées, y'a un truc qui s'appelle job, et ça se schedule. pas besoin de nettoyer la base à chaque hit.
m'enfin surtout, je vois pas trop comment ça marche ton truc, j'ai l'impression que c'est pas terrible. sur le serveur t'as activé les sessions ? si oui, utilise le session_id comme identifiant de connection, ça simplifiera tes traîtements (plus besoin de vider comme un sauvage à coup de delete massifs à chaque fois... d'autant plus que "session_onend" dans le global.asa c'est très bien pour effectuer un delete sur session_id proprement. donc tu n'aura plus qu'à faire un "insert" lors du "session_onstart", un update à chaque page, puis le delete à la fin. avec à chaque fois une seule ligne traîtée.
Marsh Posté le 14-01-2004 à 17:45:18
je te poste le système que j'utilise actuellement sur mon site ce soit. il est bien moins lourd, aussi fiable, et permet de faire la même chose.
Marsh Posté le 14-01-2004 à 19:28:19
Dans le global.asa :
|
Dans une page d'include, à appeler sur chaque page. Tu peux en faire une PS et ne pas gérer la génération de la liste des connectés
|
Les PS :
|
Et zou !
Tu peux ajouter un job qui fait un delete pour toutes les lignes de ACTIVITE dont UPDATE_TIME est de plus d'un quart d'heure et le scheduler toutes les 5 minutes si tu veux.
Marsh Posté le 15-01-2004 à 09:19:28
Le problème des session c'est que ça me donne un résultat exagérément élevé.
Là actuellement j'ai 20 utilisateurs en ligne, et 121 sessions actives.
Code :
|
C'est probablement parce que le timeout n'est pas le même : 5 minutes sur mes tables de connexion, 20 minutes sur les variables de session.
Je n'ai pas non plus envie de baisser le session.timeout, parce que les clients logués sur le site se feraient bouger à partir de 5 minutes d'inactivité. Donc, je ne peux pas trop me permettre d'utiliser ce système.
Peut-être que la bonne solution est de faire un insert à chaque fois (plus un pour loads qui n'est pas supprimable), et de gérer les delete par trigger comme tu le suggères. En plus de cela, gérer les connexions sur trois tables distinctes (une pour les anonymous, une pour les membres logués, une pour les administrateurs), afin de minimiser les risques de locks.
Marsh Posté le 15-01-2004 à 09:32:21
Non non, faut pas utiliser ce système là.
Par par la BDD et shoot les lignes qui restent trop longtemps via une requête schédulée.
Parcequ'en effet, le Session_OnEnd n'est pas toujours éxécuté, selon les version de IIS (c'est un bug connu depuis longtemps, qui est plus ou moins présent d'une version à l'autre).
Si tu shootes toute connection inactive depuis 5 minutes, ça devrait être pas mal, à condition que ce délais soit suppérieur au timeout des sessions (spécifié dans les paramètres de IIS)
Marsh Posté le 15-01-2004 à 09:34:21
Mais même si je schedule ce job pour fonctionner une fois par minute.
Durant ce lap de temps, tout chargement de page sera considéré comme une connexion si je fais un insert !?
PS : le timeout des sessions est de 20 minutes (plus pour les admin)
PS2 : le "timeout" pour une connexion, ce que je cherche à obtenir, c'est 5 minutes
Marsh Posté le 15-01-2004 à 09:35:30
OK, pour la seconde solution, en effet, j'y ai pensé aussi.
Abandonne les Session_OnStart et Session_OnEnd
Crée un trigger sur "on insert" sur la table d'activité, qui fait un update si une ligne avec l'ID existe déjà.
A chaque chargement de page, insère une ligne dans activité (ou met à jour via trigger).
Puis par schedule, shoote toutes les 5 minutes les lignes qui n'ont pas été mises à jour depuis un certan délais.
Utilise Session.SessionID comme identifiant, c'est bien mieu que l'IP, dans le cas où deux utilisateurs passent par le même proxy pour accéder au site.
Marsh Posté le 15-01-2004 à 09:37:00
Ce système te garantis une ligne par connecté, avec une durée de vie de 5 minutes, et la ligne est re-créée dès que l'utilisateur redevient actif, même si sa session n'a pas expiré
Marsh Posté le 15-01-2004 à 09:42:27
Si je résume, à chaque chargement de page j'ai :
INSERT INTO historique des pages
INSERT INTO connexions
Avec un trigger "on insert instead of" de connexions. si EXISTS(Session.SessionID) alors ne pas faire l'insert et faire un update nouvelledate = getdate()
Job qui se lance toutes les 5 minutes :
DELETE connexions WHERE date < DATEADD(minute, -5, getdate())
Marsh Posté le 15-01-2004 à 09:43:25
Je continue de penser que splitter ma table connexions en trois tables (une pour les anonymous où Session.SessionID est identifiant, l'autre pour les membres connectés où l'identifiant est UserID et l'autre pour les administrateurs où l'identifiant est AdminID) serait également une bonne chose.
Avec des tables plus légères, les risques de locks de plusieurs ressources en même temps est diminué.
Ensuite dans mon code, à chaque chargement de page :
Code :
|
Marsh Posté le 15-01-2004 à 10:09:17
LToPiQ[PPC] a écrit : Si je résume, à chaque chargement de page j'ai : |
Oui, ça me semble pas mal.
Marsh Posté le 15-01-2004 à 10:13:35
LToPiQ[PPC] a écrit : Je continue de penser que splitter ma table connexions en trois tables (une pour les anonymous où Session.SessionID est identifiant, l'autre pour les membres connectés où l'identifiant est UserID et l'autre pour les administrateurs où l'identifiant est AdminID) serait également une bonne chose.
|
je pense pas que ça pose vraiment problème. en effet, la table des connectés, même si elle sera intensivement solicitée, elle restera de toute petite taille (si t'as 1000 connections simultannées, c'est déjà que t'as beaucoup de visites, hors 1000 lignes c'est vraiment rien, à condition de pas faire des delete dedans dans tous les sens comme tu faisais avant )
pour les userID, ne pense que NULL si anonyme et le userId du gars dans un champ UserID reste mieu que plusieurs tables. après, c'est une question de goût et de besoins. si tu veux afficher "sur telle page, il y a X utilisateurs anonymes et les user suivants ..." ça sera plus facile dans une même table (un simple filtre sur la page). Mais si tu dis "y'a X mecs connus et Y anonymes sur le site", à ce moment, oui, tu peux faire x tables, ça sera limite plus simple à gérer.
Marsh Posté le 15-01-2004 à 10:15:07
Bon merci pour tes conseils je vais mettre tout ça et je vais voir ce que ça donne
Marsh Posté le 15-01-2004 à 10:51:24
j'espère que ça va résoudre ton problème
en tout cas, ça peut pas être pire que ton ancienne PS
Marsh Posté le 15-01-2004 à 10:53:09
sinon au fait, ton ancienne PS... tu pouvais pas simplement virer la transaction ? parceque c'est pas des données vitales, si à un moment ça affiche portnawak quelques minutes parcequ'une requête a planté, ça devrait pas être bien gênant, si ?
parceque rien que ça, ça permettrait je pense de fortement diminuer le risque de collisions que tu avais.
Marsh Posté le 15-01-2004 à 11:24:58
Aussi. Dans l'idéal je voulais être sûr de l'intégrité de mes données mais, en y réfléchissant, c'est pas vraiment aussi important que ça.
Marsh Posté le 15-01-2004 à 16:10:23
Bon j'ai mis ce process en place sur le serveur de dév, mais malheureusement le système par sessionid est perfectible.
Durant mes tests (5 utilisateurs qui naviguent "agressivement" sur le site), j'ai eu deux entrées pour la même personne (même ip), avec des numéros de session différents.
Il n'y avait pas de raison spéciale, la personne en question n'a pas ouvert deux navigateurs...
donc je pense que je vais devoir oublier ça
Marsh Posté le 15-01-2004 à 16:13:16
tient au passage http://forum.hardware.fr/hardwaref [...] -45212.htm
Marsh Posté le 15-01-2004 à 16:55:44
select conn_ip, count(*) as nb_ip
from connections
group by conn_ip
order by nb_ip desc
|
Toutes les ip > 1 ça serait des gars qui ont soit ouvert plusieurs fenêtres soit passent par un routeur ? J'ai des doutes.
Marsh Posté le 15-01-2004 à 17:21:45
LToPiQ[PPC] a écrit : Bon j'ai mis ce process en place sur le serveur de dév, mais malheureusement le système par sessionid est perfectible. |
c'est étrange ton truc... parceque le sessionId est identique tout au long de la session, s'il change, alors l'utilisateur perds toutes ses sessions... (et donc c'est normal qu'il soit vu comme une autre connection)
Marsh Posté le 14-01-2004 à 15:21:51
J'ai un site où, à chaque bas de page, je lance des opérations, de deux types :
- une table des connexions pour que je puisse savoir en temps réel combien sont en ligne actuellement
- un insert dans une table qui me répertorie TOUS les chargements de page, pour que je puisse tout retracer.
Pour les afficionados, voici la procédure stockée :
Mon problème est que j'ai très régulièrement des erreurs :
La transaction (ID du processus 103) a été bloquée sur les ressources lock par un autre processus et a été choisie comme victime. Relancez la transaction.
Quelqu'un aurait-il une solution pour m'éviter ces erreurs ?