Peut-on utiliser l'objet TAdsSettings dans le thread principal et les objets AdsQuery dans d'autres threads?
-
01-07-2019 - |
Question
Je suis en train de convertir une application Win-CGI en ISAPI.
L'application utilise les descendants TDataset pour le serveur de base de données Extended Systems Advantage.
Comme il ne peut y avoir qu'une seule instance d'un objet TAdsSettings, il doit être dans le fil principal.
Les objets TAdsQuery sont nécessaires dans les threads de requête.
Cela fonctionnera-t-il, c’est-à-dire que les AdsQueries dans les fils de requête récupérez les paramètres globaux de l'objet AdsSettings dans la fenêtre principale fil, et ce sera le fil sécuritaire?
La solution
Oui, ça va marcher. Le composant TAdsSettings modifie les paramètres dans le moteur Advantage Client Engine (ACE). Avec ISAPI, une instance d'ACE chargée sera utilisée par tous les threads.
Je ne le recommanderais pas, cependant. Selon les paramètres que vous modifiez, il serait plus logique d'appeler directement les API ACE. Par exemple, si vous définissez uniquement le format de date, il est plus logique d'éliminer le composant TAdsSettings et d'appeler simplement AdsSetDateFormat60, qui prend un descripteur de connexion. La suppression du composant TAdsSettings élimine de nombreux appels pour définir les paramètres globaux ACE. Un grand nombre de ces appels doivent comporter un objet de synchronisation pour que toutes les connexions soient désactivées pendant que le global est modifié. Cela aura un impact négatif sur les performances, en particulier dans une application multithread telle qu'une application Web. Faites plutôt des appels qui fonctionnent sur le descripteur de connexion spécifié.
Vous pouvez obtenir le descripteur de connexion en référençant la propriété TAdsConnection.Handle ou en appelant la méthode TAdsQuery.GetAceConnectionHandle.
Autres conseils
Assurez-vous que les AdsQueries utilisent Synchronize pour accéder directement aux TAdsSettings (ou utilisez un système de messagerie pour communiquer entre les threads de travail et le thread principal au lieu d’y accéder directement) s’ils ne sont pas dans le thread principal (c'est-à-dire System.MainThreadID <> Windows.GetCurrentThreadID
)
J'ai également posé cette question dans le groupe de discussion: devzone.advantagedatabase.com, Advantage.Delphi
Par souci d'exhaustivité, je vais ajouter une question / réponse à partir du reste de ce fil de discussion:
Question (moi):
La plupart des requêtes des threads ne sont actuellement pas attachées à un Objet TAdsConnection. Je prévois de créer une connexion pour chaque fil pour ces " orphelin " requêtes à utiliser, mais c'est une grande application et cela prendra du temps. Je suis également à peu près sûr que le seul non-défaut La propriété de l'objet TAdsSettings est l'ensemble de types de serveur, qui peut également être défini dans le composant de connexion, donc une fois que toutes les requêtes sont lié aux connexions, le composant paramètres ne sera pas nécessaire. Je vais regarder en appelant directement l'API de configuration comme alternative.
En attendant, j'ai une question à propos des threads et des requêtes. sans composant de connexion attribué. J'ai noté dans les fichiers d'aide que si les requêtes de plusieurs threads partagent un seul objet de connexion, la les requêtes seront exécutées en série plutôt que simultanément. Avec un objet de connexion dans chaque fil, cela ne devrait pas être un problème, mais je suis s'interroger sur les requêtes qui ne n'ont pas d'objet de connexion attribué. Seront-ils considérés comme étant sur des connexions indépendantes de le point de vue de la concurrence multithreading, ou seront-ils considérés comme étant sur le même lien et doivent donc céder à chaque autre?
Réponse (Jeremy):
Vous devrez résoudre ce problème. Ils vont juste chercher une liste globale de connexions pour en trouver un avec le même chemin, et ils utiliseront cette connexion. Pas bon dans une application multithread.
Ainsi, d'après la réponse de Jeremy, il est préférable de créer au moins un objet TAdsConnection pour chaque thread et de vous assurer que toutes les requêtes y sont attachées, sinon la sérialisation risque de se produire.