Gestion du cache avec ADO

Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
-
Bonjour,

Je ne sais pas trop si je dois poser ma question ici ou sur le forum C++ (je ne peux pas faire les deux, si un admin passe et que ma question n'a pas sa place ici, je l'invite à la déplacer ;) )

Ma question est toute simple (enfin de mon point de vu). Comment gérer PROPREMENT le cache de maj avec les objets ADO ?

En situation :
Je modifie les données d'une base (SQL Serveur dans le cas présent). Plusieurs tables sont modifiées dans une même fenêtre (une table "maitre" et 3 tables "détails"). Et je voudrais un bouton "Valider" et "Annuler" sur cette fenêtre.

Mon problème :
Les objets ADO (TADODataQuery comme TADODataSet, et TADODataTable, même si je n'ai pas fait beaucoup de tests avec le DataTable) font leur maj en base "au fil de l'eau" (au changement de ligne active la requête UPDATE est envoyée au serveur).
Naturellement j'ai pensé : un Begin à l'ouverture de l'écran et un Commit à la fermeture. Sauf que SQL Serveur Lock des tables, et comme plusieurs utilisateurs seront connectés simultanément, cette solution n'est pas acceptable (une gestion est prévue pour que deux utilisateurs ne puisse pas accéder en modification aux même données). Je cherche, un peut partout, un peut plus même, mais je ne trouve pas de solution "standard" :/.

Quel est selon vous la solution la plus efficace et propre pour faire ça ? (j'ai lu ici http://www.developpez.net/forums/d1125691/environnements-developpement/delphi/bases-donnees/gestion-cache-ado/ qu'avec les objets ADO, c'était au SGBD de s'occuper de la gestion du cache, mais je ne vois pas bien comment m'y prendre)

Merci d'avance

PS :
Je développe sur C++Builder5 avec Ms SQL Serveur 2008


Amicalement
Afficher la suite 

10 réponses

Messages postés
1284
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
11
0
Merci
Bonjour,

Je pense que tu dois effectivement démarrer et "commiter" tes transactions pour que les enregistrements soient appliqués en base (en tous cas, sous delphi avec les DBX ça marche comme ça). En revanche, si tu veux pouvoir accéder à des enregistrements de tes tables en cours de modification, c'est à dire outre passer les locks, c'est sur le niveau d'isolation de tes transactions (apparemment défini sur ton composant TADOConnection) qu'il faudra jouer :
http://docwiki.embarcadero.com/Libraries/XE6/fr/Data.Win.ADODB.TADOConnection.IsolationLevel
Commenter la réponse de sp40
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
0
Merci
Bonjour et merci de ta réponse :)

Malheureusement ça ne fonctionne pas.
A en croire le lien que tu m'a envoyé ça devait être ça, mais ça marche pas. Une fois la 1ere requête UPDATE reçu par le serveur sur une table, cette table se retrouve "lock".
SQL-Serveur ne supporte peut être pas ce type de fonctionnement ???

D'autre suggestion ?
Commenter la réponse de Polack77
Messages postés
1284
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
11
0
Merci
Ah... Il semblerait que si pourtant, à en croire ces docs...
https://msdn.microsoft.com/fr-fr/library/ms173763.aspx
https://msdn.microsoft.com/en-us/library/ms378149%28v=sql.110%29.aspx

N'ayant qu'une petite expérience de SQLServer, je n'ai malheureusement pas d'autres suggestions à te faire...
Commenter la réponse de sp40
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
0
Merci
Ha... J'ai compris :
En fait je ne veux pas que mon application contourne le Lock, mais il faut que le lock n'ait pas lieu du tout :

Plusieurs applications différentes fonctionnent sur cette même base de données (certaines en lecture seule d'autre en lecture écriture). Donc même si mon appli contourne les lock (ça je n'ai pas tester à vrai dire) cette solution n'est pas convenable.

Mon test à valider :
- Je commence mes modifs sur mon application et "valide" une ligne (je change simplement de ligne sur un query, ce qui lance la requête UPDATE, si je pouvais déporter cet UPDATE à la validation de la form, ça me conviendrait parfaitement ;) ) mais pas l'ensemble de la saisie.
- Je lance une requête SELECT (depuis Manageur Studio) sur une des tables modifiées. Il faut que cette requête réponde, et que mes modifs ne soient pas appliquées.
- Je valide ma saisie sur mon application (peut-être 20 minutes plus tard)
- Je lance de nouveau une requête SELECT sur cette table qui cette fois contient les modifications.

Je ne pourrais pas faire valider de modifier l'ensemble des applications connectées à ce SGBD (surtout que je suis nouveau dans cette ste ^^)

Amicalement
Commenter la réponse de Polack77
Messages postés
1284
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
11
0
Merci
A priori si tu veux "déporter" un ou plusieurs update, ce sera grâce à la validation d'une transaction, non ?
Après, si quelque soit le niveau d'isolation que tu choisis pour ton AdoConnection tu te retrouves avec l'impossibilité d'accéder à ta table, c'est que le problème vient d'ailleurs.

Dans ton test, est-ce que avant la première étape (c'est à dire l'update), si tu fais un select, tu arrives à avoir le résultat de ta requête ou bien est-ce que déjà à ce niveau tu n'obtiens pas de réponse ?

Dans l'étape 2, SELECT depuis Manageur Studio, est-ce que tu obtiens une réponse ?

Simon
Commenter la réponse de sp40
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
0
Merci
Oui (avant la 1ere étape j'accède bien aux données)
Par contre une fois la 1ere étape faite, si je lance un select, je n'aurais la réponse qu'une fois le COMMIT (ou ROLLBACK) fait par mon appli (ce qui pourrais être long)
Commenter la réponse de Polack77
Messages postés
1284
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
11
0
Merci
Et en modifiant le niveau d'isolation avant de te connecter à ta base, tu n'arrives à rien ? C'est bizarre parce qu'à mon avis ça vient vraiment de là... Tu peux poster ton code ?

Commenter la réponse de sp40
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
0
Merci
Non (en modifiant le niveau d'isolation je n'arrive à rien).
J'ai testé cette séquence avec tout les modes d'isolations, pour un comportement systématiquement identique.

Je pense que cela doit modifier le niveau d'isolation de ma connexion, mais pas celle du serveur. En gros, avec la config qui vas bien, mon application pourrait accéder à des table verrouillées mais ce n'est pas pour autant qu'elle ne verrouillera pas de table (enfin c'est ce que je suppose au vue des résultats de mes tests & des docs)

Edit :
Mais je ne suis pas le seul à utilisé cette connexion, et je n'ai pas valider que rien ne n'altère la config que je fait dans le degin...

Je vais re-tester avec MA connexion cet fois (mais je m'attend à un comportement identique :/ )

Bon ça coutait pas grand chose de valider ça, mais non je confirme ça lock bel et bien les tables.
Les isolations levels testés (soit tout ceux à ma dispo dans mon obj de connexion) :
ilBrowse KO
ilChaos KO
ilCursorStability KO
ilIsolated KO
ilReadCommitted KO
ilReadUncommitted KO
ilRepeatableRead KO
ilSerializable KO
ilUnspecified KO

Amicalement
Commenter la réponse de Polack77
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
0
Merci
Oui il semblerait que les isolation level interviennent sur la connexion courante, pas sur l'application des règles de fonctionnement des locks (ce qui me fait dire ça : http://blogs.codes-sources.com/christian/archive/2007/03/08/sql-server-les-verrous-et-l-utilisation-de-nolock.aspx ici on set le niveau d'isolation avant de faire des selects pas des updates :/)
Commenter la réponse de Polack77
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
0
Merci
Oups, j'avais pas vu que tu demandais à voir mon code :*)

Heee ba je vais pas vraiment pouvoir, ça vas faire BEAUCOUP de code :/

Pour reproduire ce que j'ai :

Sur un form placer :
3 ADOCommand (BEGIN, COMMIT, ROLLBACK, je détail pas le contenu des requêtes xD)
1 ADOConnection
n ADOQuery (avec des SELECT tout simple et des relation faite via le DataSource des Querys "détails", les paramètres étant nommés exactement comme les colonnes de la table "maitre" les liens "maitre"/"détail" se font tout seul)

A l'ouverture du form, exécuter le code de l'ADOCOMMAND_COMMIT

Effectuer une modif d'une donnée d'un query puis changer de ligne (une requête UPDATE sera alors envoyé automatiquement a la base)

Exécuter une requête de sélection sur la même table depuis autre-part (Manageur Studio par exemple)

On constate que Manageur Studio ne répond pas

Executer soit ADOCommand_COMMIT soit ADOCommand_ROLLBACK

Pouf Manageur Studio réagit de renvois les lignes demandées

(désolé mais mon form contiens déjà environ 50 objets pour 4 ADOQuerys alors ça risque de faire un peut lourd pour être posté sur fofo)

PS :
Ma connectionString est :
Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=***;Data Source=***;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=***;Use Encryption for Data=False;Tag with column collation when possible=False

J'ai pas vérifié les options ici ! Je regarderais en détail demain ;)
Mais à 1ere vue rien d'exotique

Bonne soirée :)

Amicalement
Polack77
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
-
Bonjour :),

Je confirme qu'il n'y a rien d'exotique dans cette chaine de co, faut chercher d'un autre coté (ou j'ai un problème de vision au réveil, c'est possible ^^)

Tu voulais mon code (au fait je tutoie toujours sur fofo, si ça "vous" dérange dite le moi ;)).
Je peut en faire un simplifié. Mais, pourras tu l'ouvrir ? Builder C++ v5
Si non, le veux tu compilé ?
Si non, que veux tu (je n'aurais à ma dispo Visual Studio ou autre compilo que ce WE, mais pas certains que les objets ADO soient exactement les même :/)

PS :
Même si je préférerais, ça ne sera pas possible de changer de langage pour mon projet (et donc mon probl initiale :/ )
sp40
Messages postés
1284
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
11 > Polack77
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
-
Pas de souci avec le "tu"... :)
Pour les sources, ça serait bien la partie correspondante à ton test. Si ça te dérange de le poster ici, contactes moi en MP...
Polack77
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
> sp40
Messages postés
1284
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
-
Non compilé du coup ?
(pck beaucoup de choses sont défini dans le designeur, donc vas falloir le projet à proprement parler, enfin l'ensemble des fichiers de définition, soit un .h un .cpp et un .dfm, si non je détail simplement tout ça, avec des requêtes de création de table test, et tout et tout ^^).
Polack77
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
-
J'aurais été pas mal occupé en final aujourd'hui :/
Je prépare ce qu'il faut pour que mon probl soit + reproductible durant le we (fait des tests sur un MySQL/PosgreSQL/SQLite/???, le tout avec un compilo gratos qui implémente les mêmes obj, quand, et si, j'ai de quoi "présenter" mon probl je reviens vers vous ;) )

PS :
Si qq'un a une idée SURTOUT qu'il n'hésite pas ;)

Bonne fin de journée :)
Commenter la réponse de Polack77