Précédent   Forum des professionnels en informatique > Bases de données > Oracle
Oracle Forum Oracle : le serveur, les outils, ... Voir F.A.Q Oracle Tutoriels Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 20/11/2007, 11h09   #1
Membre à l'essai
 
Avatar de schnourf
 
Inscription : mars 2003
Messages : 66
Détails du profil
Informations forums :
Inscription : mars 2003
Messages : 66
Points : 20
Points : 20
Par défaut Trouver qui lock un enregistrement (pas bloque)

Bonjour,

dans la boite ou je suis, pour empecher que les utilisateurs modifient la même ligne en même temps, nous faisant un
Code :
SELECT * FROM TABLE1 WHERE TBL_ID = 12345 FOR UPDATE NOWAIT
Dans notre application nous avons un bouton modifier que met l'application en mode modification et donc sur ce bouton on fait le "SELECT FOR UPDATE NOWAIT" -> si on recoit un exception c'est que c locker sinon on passe en mode modification.

Quand l'utilisateur reçoit l'exception, j'aimerai bien afficher un message d'erreur lui disant que tel ou tel autre personne est entrain de modifier pour cela j'ai fait
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
	SELECT substr(object_name,1,20) "Object",
  substr(os_user_name,1,10) "Terminal",
  substr(oracle_username,1,10) "User",
  OBJECT_TYPE "Type",  
  A.OBJECT_ID, ROW_WAIT_OBJ#, ROW_WAIT_FILE#, ROW_WAIT_BLOCK#, ROW_WAIT_ROW#,
  dbms_rowid.rowid_create ( 1, ROW_WAIT_OBJ#, ROW_WAIT_FILE#, ROW_WAIT_BLOCK#, ROW_WAIT_ROW#)
FROM
  SYS.V_$LOCKED_OBJECT A,
  SYS.ALL_OBJECTS B,
  SYS.V_$SESSION c
WHERE
  A.OBJECT_ID = B.OBJECT_ID AND
  C.SID = A.SESSION_ID
et j'ai remarqué que A.OBJECT_ID est different de ROW_WAIT_OBJ#, ce qui à mon sens est normal vu que personne n'est bloqué et en attente.

A.OBJECT_ID represente TABLE1 tandis que ROW_WAIT_OBJ# une autre TABLE X

Ceci reprensente un probleme car je ne peux pas recupere le rowid de la ligne lockée dans TABLE1 car dbms_rowid.rowid_create ( 1, ROW_WAIT_OBJ#, ROW_WAIT_FILE#, ROW_WAIT_BLOCK#, ROW_WAIT_ROW#) me donne le ROWID dans TABLE X.

Est-ce que vous avez une autre solution à me proposer ??

Merci beaucoup
schnourf est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2007, 17h14   #2
Expert Confirmé
 
Inscription : février 2006
Messages : 3 433
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 3 433
Points : 3 462
Points : 3 462
Citation:
A.OBJECT_ID represente TABLE1 tandis que ROW_WAIT_OBJ# une autre TABLE X
J'ai fait un petit test avec la 10.2.0.2 sur XP et je trouve bien que ROW_WAIT_OBJ# identifie dans DBA_OBJECTS la table dont la ligne est verrouillée et sur laquelle il y attente.

Pourquoi faire un jointure avec SYS.V_$LOCKED_OBJECT et SYS.ALL_OBJECTS ? Je ferais plutôt une jointure seulement avec ALL_OBJECTS.

J'ai un doute sur l'algorithme utilisé ROW_WAIT_ROW# est seulement valide si une transaction attend sur une autre transaction. Avec NOWAIT, il n'y a pas d'attente

Citation:
ROW_WAIT_ROW# NUMBER Current row being locked. This column is valid only if the session is currently waiting for another transaction to commit and the value of ROW_WAIT_OBJ# is not -1.
Merci de préciser la version exacte d'Oracle utilisée.
__________________
P. Forstmann

AskTom Forums OTN doc 8, 9, 10 et 11
pifor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/11/2007, 21h46   #3
Membre confirmé
 
Avatar de DAB.cz
 
Inscription : octobre 2006
Messages : 221
Détails du profil
Informations forums :
Inscription : octobre 2006
Messages : 221
Points : 214
Points : 214
Je crois que pour garantir accès unique au enregistrement (éventuel affichage d'utilisateur modifiant à l'heure actuelle), creation de propre "LOCKTAB" table est la meilleur solution.

Code :
1
2
3
4
5
6
LOCKTAB
  id number
  sessionid number
  lockdate date
  utilisateur number
  ...
Si l'utilisateur veut modifier la ligne, il devrait insérer dans LOCKTAB tout d'abord. Est au fin de mode modification, il devrait effacer de LOCKTAB.
Beaucoup de travail, beaucoup de problèmes, mais on peut éviter V_$*LOCK*.

Votre avis?

DAB
DAB.cz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 11h57   #4
Membre à l'essai
 
Avatar de schnourf
 
Inscription : mars 2003
Messages : 66
Détails du profil
Informations forums :
Inscription : mars 2003
Messages : 66
Points : 20
Points : 20
Bonjour, tous d'abord pour repondre a Pifor

La version d'oracle de 10G release 2
Ensuite pour moi c'est clair que avec NOWAIT, il n'y a pas d'attente, et que je ne puisse pas utilisé ROW_WAIT_ROW#

Mais il doit bien y avoir un moyen de trouver la ligne lockée, sans passer pas une table intermediaire comme le propose DAB.cz

Je vais te montrer ce que je fais

A partir de mon application (.NET 2.0) je fait
Code :
SELECT * FROM vorschlag WHERE vor_id = 12345 FOR UPDATE nowait
Ensuite
Code :
1
2
3
4
SELECT a.OBJECT_ID, object_name, A.SESSION_ID FROM
V_$LOCKED_OBJECT A, ALL_OBJECTS B
WHERE A.OBJECT_ID = B.OBJECT_ID
AND oracle_username = 'EDV_1'
me donne ce resultat
Code :
1
2
OBJECT_ID   OBJECT_NAME   SESSION_ID
63311          VORSCHLAG     133
ce qui est correct.

si je fait
Code :
1
2
3
4
SELECT OBJECT_ID, object_name, ROW_WAIT_OBJ#
FROM V_$SESSION, ALL_OBJECTS
WHERE ROW_WAIT_OBJ# = OBJECT_ID (+)
AND username = 'EDV_1'
j'obtiens
Code :
1
2
3
 
OBJECT_ID  OBJECT_NAME  ROW_WAIT_OBJ#
NULL            NULL                 88918
quand je fait mon select for update nowait à partir de TOAD, ROW_WAIT_OBJ# à la valeur -1;

voila si ça peut aider quelqu'un a comprendre le probleme
schnourf est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 12h50   #5
Expert Confirmé
 
Inscription : février 2006
Messages : 3 433
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 3 433
Points : 3 462
Points : 3 462
Citation:
Mais il doit bien y avoir un moyen de trouver la ligne lockée, sans passer pas une table intermediaire comme le propose DAB.cz
Je ne crois pas qu'il y a de moyen simple de faire ça avec des vues V$ car:
  • les verrous posés sur des lignes sont écrits par Oracle dans les blocs des données et non dans une structure spécifique de la SGA
  • V$LOCK enregistre les demandes de verrous sur des lignes au niveau de la table concernée et non au niveau des lignes: si vous verrouillez 10 lignes différentes d'une même table en exclusif, vous n'aurez qu'une seule ligne dans V$LOCK (et non 10).
__________________
P. Forstmann

AskTom Forums OTN doc 8, 9, 10 et 11
pifor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 16h50   #6
Membre à l'essai
 
Avatar de schnourf
 
Inscription : mars 2003
Messages : 66
Détails du profil
Informations forums :
Inscription : mars 2003
Messages : 66
Points : 20
Points : 20
Ok, donc soit je passe par une table intermediare, soit je mentionne dans le message d'erreur tout les utilisateurs qui lockent quelque chose (il n'y en a jamais plus que 5, en général 1-2).

Merci quand même.
schnourf est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2007, 16h51   #7
Membre à l'essai
 
Avatar de schnourf
 
Inscription : mars 2003
Messages : 66
Détails du profil
Informations forums :
Inscription : mars 2003
Messages : 66
Points : 20
Points : 20
C'est quand même dommage qu'il n'y pas de table V$ qui donne ce genre de renseignements.
schnourf est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h58.


 
 
 
 
Partenaires

Hébergement Web