rastasponch
Messages postés27Date d'inscriptionjeudi 12 août 2004StatutMembreDernière intervention19 décembre 2009
-
30 juin 2006 à 14:49
rastasponch
Messages postés27Date d'inscriptionjeudi 12 août 2004StatutMembreDernière intervention19 décembre 2009
-
10 juil. 2006 à 10:20
Bonjour à tous,
Je développe actuellement sous VB6 et accéde une base de données MS SQL Server via ADO. Mon problème est le suivant : lors de l'écriture (ou mise à jour) je souhaiterai bloquer l'accès en lecture pour les autres utilisateurs..
J'ai compris (bien que difficilement et manifestement pas suffisamment) les systèmes de verrouillage mis en place par ADO.
J'utilise un cusreur serveur (CursorLocation AdUseServer) et un verrou de type Pessimiste (LockType AdLockPessimistic)
Quel est le code à récupéré par l'erreur soulevé ? ?
Je ne trouve pas de moyen de m'en sortir...merci pour votre aide !
A voir également:
L'enregistrement des modifications n'est pas autorisé sql server
cs_pluplu
Messages postés615Date d'inscriptionmercredi 18 décembre 2002StatutMembreDernière intervention 4 juillet 2012 30 juin 2006 à 19:52
En mode Pessimiste le premier utilisateur qui accède au données en modification bloque l'accès de celles-ci. En mode Optimiste c'est seulement lors de l'update que le blocage d'accès au données est fait ce qui réduit le temps de monopolisation de celles-ci, donc la première méthode est plus sure mais pénalisante pour les autres utilisateurs, la seconde est plus souple mais plus exposée au conflit d'accès concurant. Il faut faire un choix au cas par cas et quelque fois ajouter un peu de code pour palier à l'un ou l'autre de ces problèmes
rastasponch
Messages postés27Date d'inscriptionjeudi 12 août 2004StatutMembreDernière intervention19 décembre 2009 2 juil. 2006 à 11:14
Bonjour pluplu et merci de ta réponse.
Après avoir fait quelques tests, je pense utilisé le blocage pessimiste dans la plupart des programmes ou l'ajout / modification d'enregistrement est autorisé. Or j'aurais souhaité affiché un message du style "Vous ne pouvez lire cette enregistrement, un autre utilisateur cherche à le modifier actuellement"...
Savez-vous comment je peut savoir qu'un accès concurrant à lieu à ce moment ?
J'ai essayé d'utilisé la méthode .EditMode, malheureusement elle génére quoi qu'il arrive une erreur.
Je sais qu'il s'agit d'un cas d'école et qu'il est très rare que 2 personnes modifie simultanément la même donnée, toutefois c'est un test à faire pour être optimale !
cs_pluplu
Messages postés615Date d'inscriptionmercredi 18 décembre 2002StatutMembreDernière intervention 4 juillet 2012 2 juil. 2006 à 19:32
Voici un petit exemple en utilisant le retour d'erreur d'un contrôle ADODC
Private Sub Retrieve_User()
Dim Userlock As Boolean 'détermine si le profil est suspendu
On Error GoTo Errorhandler
Init_DB 'Initialise les infos pour ouvrir la base de donnée
Sql_Str = "Select * from Users Where Users.Ident like '" & Rtext_Ident.Text & "'"
With Adodc1
.ConnectionString = sConnection
.RecordSource = Sql_Str
End With
Adodc1.Refresh
' Si le user existe, donne son dernier accès
Lbl_Status = "Dernière Connection, le " & Adodc1.Recordset.Fields![Last_Access].Value
' On vérifie si le compte utilisateur n'est pas suspendu !!
If Userlock Adodc1.Recordset.Fields![Userlock].Value False Then Err.Raise vbObjectError + 513
Exit Sub
Errorhandler:
Select Case Err.Number
Case vbObjectError + 513 'le compte User est suspendu
Rtext_Ident.Text = ""
Lbl_Titre = "Ident suspendue!"
Lbl_Texte = "Votre Identification est Suspendue," _
& "en cas de besoin contactez votre Administrateur système."
Rfra_Erreur.Visible = True
Case 3021 'Ident incorrect
Rtext_Ident.Text = ""
Lbl_Titre = "Ident incorrect!"
Lbl_Texte = "Votre Identification est innexistante ou incorrecte," _
& "en cas de besoin contactez votre Administrateur système."
Rfra_Erreur.Visible = True
Case -2147217843 'La base est ouverte en mode exclusif
Rtext_Ident.Text = ""
Lbl_Titre = "Acces impossible"
Lbl_Texte = "La base de donnée est ouverte en mode exclusif," _
& "en cas de besoin contactez votre Administrateur système."
Rfra_Erreur.Visible = True
' Case -2147467259 'La base est en cours d'utilisation
Case Else 'Une autre erreur s'est produite
Rtext_Ident.Text = ""
Lbl_Titre = "Erreur système!"
Lbl_Texte = "Une erreure système est intervenue : " & Err.Number _
& " Désignation : " & Err.Description & ". En cas de besoin contactez votre Administrateur système."
Rfra_Erreur.Visible = True
End Select
End Sub
Je n'ai pas la liste des error code renvoyés par ADO mais celle-ci doit se trouver sur MSDN
rastasponch
Messages postés27Date d'inscriptionjeudi 12 août 2004StatutMembreDernière intervention19 décembre 2009 7 juil. 2006 à 11:14
Salut pluplu,
merci pour ton code, cela m'a aidé pour trouvé les codes d'erreurs.
Toutefois, il semble que seule l'erreur n° 3021 soit traitée au niveau de l'objet Recodset.open lorsqu'un utilisateur accède une donnée déjà en consultation par un autre utilisateur.
Après plusieurs test, je n'ai pas trouvé comment redonné la main à l'utilisateur (si ce n'est en fermant la connection puis en la ré-ouvrant aussitôt)
De plus il semblerait que le verrou ne bloque pas uniquement l'enregistrement en cours mais toute la table.
Donc ma question se transforme en : "Comment déverrouillé ?"
________________________________________
Ici je met mon code :
________________________________________
Private Sub Text1_LostFocus()
On Error GoTo erreurecriture1
Dim lib, stk As String
If Text1.Text <> "" Then
''' Limitation de la valeur du champ
If Val(Text1.Text) < 1 Or Val(Text1.Text) > 9999 Then
''' Message d'erreur
MsgBox "Code erroné. (le code ne peut être inférieur à 0 ni supérieur à 9999)"
Text1.Text = "": Text1.SetFocus
Else '# Sinon
Text1.Text = Int(Val(Text1.Text)) 'Conversion en entier
truc:
''' Exécution d'une requête
ObjetRecordset.Open "SELECT * FROM Article WHERE AR_Code=" & Text1.Text & " ;", ObjetConnection, adOpenDynamic, adLockPessimistic, -1
''' Récupération de l'enregistrement s'il existe déjà dans la table
If Not (ObjetRecordset.EOF) Or (ObjetRecordset.EditMode = adEditNone) Then
lib = ObjetRecordset("AR_Libelle")
stk = ObjetRecordset("AR_Stock")
End If
''' Si les variables n'ont pas de résultat, elle ne sont pas
''' affecté, donc l'article n'existe pas.
If lib <> "" And stk <> "" Then
Text2.Text = lib
Text3.Text = stk
Else
MsgBox "Saisir un article." Text2.Text "": Text3.Text ""
Text2.SetFocus
End If
End If
End If
erreurecriture1:
Select Case Err.Number
Case 3021 'Ident incorrect
MsgBox "Consultation impossible.", , "Erreur..."
If ObjetRecordset.State = 1 Then
ObjetRecordset.Close
End If
'# Marche pas
'Set ObjetRecordset = Nothing
'Set ObjetRecordset = New ADODB.Recordset 'Recordset pour la lecture (SELECT)
'# Marche pas
'ObjetRecordset.Cancel
'ObjetRecordset.CancelUpdate
'ObjetRecordset.CancelBatch
'# Marche
ObjetConnection.Close
''' Test réussite fermeture
If ObjetConnection.State = 0 Then
MsgBox "La base est fermée."
End If
ObjetConnection.CursorLocation = adUseServer 'Curseur côté Serveur
ObjetConnection.Mode = adModeWrite 'Mode Ecriture
''' Chaine de connexion
ObjetConnection.ConnectionString = "Provider=SQLOLEDB.1;Data Source=EPSON\EPSON;User ID=XXXXX;Password=XXXXX;DATABASE=TEST;Net=dbnmpntw;"
''' Connexion via objet ADODB
ObjetConnection.Open
Resume truc
________________________________________
merci pour ton aide
Vous n’avez pas trouvé la réponse que vous recherchez ?
Ceci ne me semble pas correct dans ton code, car pour savoir si un enregistrement existe ce n'est pas en testant ObjetRecordset.EOF, mais en contrôlant la propriété recordcount.
''' Récupération de l'enregistrement s'il existe déjà dans la table
If Not (ObjetRecordset.EOF) Or (ObjetRecordset.EditMode = adEditNone) Then
peut être avantageusement remplacé par:
If ObjetRecordset.recordcount < 1 then ' Si le recordset est vide alors ....
rastasponch
Messages postés27Date d'inscriptionjeudi 12 août 2004StatutMembreDernière intervention19 décembre 2009 10 juil. 2006 à 10:20
J'ai déjà lu, relu et re-relu les documents vers lesquels tu me redirige...et d'après mon analyse, ce choix de curseur (adLockPessimistic) me semble absolument appropié à la situation. En effet, il s'agit du seul curseur permettant de bloquer totalement l'accès à un enregistrement (dès sa lecture).
Dans le but de migrer de DAO vers ADO, il remplace de façon adéquat la propriété LockEdit de DAO, qui, elle, bloque l'accès dès la première lecture.
En ce qui concerne le test "If ObjetRecordset.RecordCount < 1 then", je ne vois pas l'avantage d'une telle méthode. (D'après mes tests la valeur recordcount est toujours égale à -1 avec un curseur côté server (adUseServer)). De plus ce test ne vérifie pas l'accès concurant à un enregistrement (.EditMode). A priori, tu utilise un curseur de type AdUseClient, dans ce cas comment gère tu les accès concurant ? (d'après ton code, tu dispose d'une table contenant les utilisateurs, ce qui n'est pas mon cas)
Enfin, dans le cas d'une gestion de numéro de facture, les numéros doivent se suivre (sinon gare au fisc !), comment attribué ce numéro au premier accès ? Cela ne me semble pas possible avec un curseur côté client, puisque le numéro attribué ne sera pas stocké dans la base (mais belle et bien sur le poste client), un autre utilisateur peut donc se retrouver avec le même numéro...