Bonjour,
Je me suis toujours posé cette question. Pour une connection Bdd utilisé pour l'ensemble d'un site Web, faut il faire une classe static de connection ou un singleton ou juste une classe que j'instancierais ?
Merci
Version imprimable
Bonjour,
Je me suis toujours posé cette question. Pour une connection Bdd utilisé pour l'ensemble d'un site Web, faut il faire une classe static de connection ou un singleton ou juste une classe que j'instancierais ?
Merci
Hello,
Utiliser une classe static c'est très bien. Utiliser de design pattern Singleton pour une connexion base de donnée pour une application Web c'est à discuter.
si tu veux qu'une seule connexion pour toutes les sessions Web (ou tous les utilisateurs qui se connectent à ton site web) alors dans ce cas oui.
Maintenant comme la plupart des fournisseurs utilisent le pool de connexion tu n'as plus à te soucier de cela. tu peux créer une connexion à chaque requête de base de donnée. Ainsi tu es sur d'avoir un contexte de base de données spécifique pour le traitement en cours.
Je ne veux pas une seule connection pour mon site, je veux une utilisation normale.
Donc c'est le pool qui s'occupera de ca.
Donc static c'est ce que tu recommandes ? Car la difference entre un singleton et static n'est pas evidente.
Le fait d'utiliser une classe static est d'éviter de passer par une instanciation pour accèder au contenu de la classe.
Oon utilise une classe static pour l'implémentation du singleton. Cette classe doit en plus vérifier si la connexion est unique dans le sens qu'on vérifie qu'elle n'existe pas avant d'en créer une autre.
La classe static sans l'implémentation du singleton permet de créer tout le temp une connexion à la base de données.
A+
Pour moi l'utilisation d'un singleton c'est justement pour ne pas utiliser une class static.
Elle verifie effectivement si l'objet est deja instancié ou non et renvoi la meme instance ou en cree une si rien n'existe.
Dans les 2 cas, est ce gerer par le pool de connection ?
Est ce qui si 100 utilisateurs se conenctent au meme site, ils utliseront 100 connections (1 par utilisateur et rien qu'une ?) ou 1 seule pour les 100 utilisateurs ?
Vous vous prenez la tête pour rien.
T'as besoin d'accéder à la base:
- tu crées une DbConnection
- tu l'ouvres
- tu fais ta requête
- tu la fermes
Le framework s'occupe du reste. Il gére le pool de connexions, prend une connexion dispo quand il en a besoin, agrandit le pool si nécessaire...
La question c'est tu le fait dans une classe static, non static, singleton ?!? et la derniere question c'est :Citation:
tu crées une DbConnection
- tu l'ouvres
- tu fais ta requête
- tu la fermes
J'ai besoin de comprendre reeelementce qui se passeCitation:
Est ce qui si 100 utilisateurs se conenctent au meme site, ils utliseront 100 connections (1 par utilisateur et rien qu'une ?) ou 1 seule pour les 100 utilisateurs ?
Static ou non static, a la limite, c'est secondaire...ca depdends si tu veux faire :
ouCode:dbHelper.ExecuteNonQuery("database","delete from user where id = 1");
;)Code:
1
2
3 DatabaseWrapper dbHelper = new DatabaseWrapper("database") dhHelper.ExecuteNonQuery("delete from user where id = 1");
Par contre, Singleton, bof, bof...a moins que tu veuilles qu'un seul utilisateur accede a la base de donnees a un instant t...
Et la reponse est...ca depends...ca depends du nombre d'utilisateurs conenctes, de la duree de tes requetes, etc...Citation:
Est ce qui si 100 utilisateurs se connectent au meme site, ils utliseront 100 connections (1 par utilisateur et rien qu'une ?) ou 1 seule pour les 100 utilisateurs ?
si tu as 5 utilisateurs qui font une requete en meme temps, ils vont utiliser 5 connections differentes, par contre, si un 6eme arrive alors que le premier vient de finir, le mecanisme de pooling va recuperer la conenction qui vient d'etre liberee...
Pour avoir 100 connexions ouvertes en meme temps, il faut que 100 utilisateurs soient en train de faire une requete (ou que tu ne fermes pas les connections ;) )
Donc le pool de connection se charge de tout (genial), et cela peut importe de l'utilisation static, non static ou singleton alors.
C'est bien ca ?
http://msdn.microsoft.com/fr-fr/library/8xx3tyca.aspx
c'est ca...sauf que si tu utilises un singleton, tu vas empecher tes utilisateurs de travailler sur ton objet tant qu'il est utilise par un autre utilisateur...
Merci pour ces precision.
Je vais lire ta page.
Sinon dans quelle contexte utilise t on les singletons ? je ne vois aucun cas concret pour un site web. Pour les logs peut etre ?
Dans le cas où tu veux qu'une seule objet d'une classe disponible pour plusieurs demandeur au lieu et place d'un objet par demandeur
Je sais bien a quoi sert le singleton, main en pratique je n'ai jamais eu le cas !!! c'est pour ca que je demande des exemples concrets
Honnetement ?
Je crois que je n'ai pas trouve une seule *vraie* necessite d'utiliser un singleton en 8 ans...
a moins que tu n'aies un objet dont l'initialisation est tres couteuse, je ne vois pas de vrai avantage...a moins que tu doives designer un systeme ou fonctionellement, tu doives assurer l'unicite d'une ressource, ce qui arrive tres rarement
Bonjour,
J'arrive au milieu de votre discussion....
Concernant les Singletons, vous ne les utilisés pas pour faire des mécanismes de logs, de caches (cache de données, ou de configuration)?
Je trouve ça assez pratique, même si comme vous le dites ce n'est pas une nécessité.
pour les logs, j'utilise log4net, qui marche bien (pas la peine de reinventer le roue ;) )
Pour les caches, des classes statiques, avec un lock si elles doivent charger une quantite importante de donnees
Même si vous êtes contraints de logger dans le journal Windows....
Dans ce cas la, je crois que tu as le EventLogAppender
(tiens, faudrait que je blogues ca ;) )Code:
1
2
3
4
5
6 <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender"> <param name="LogName" value="MyLog" /> <param name="ApplicationName" value="MyApp" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /> </layout>
OK, merci pour cette info.
Je suis nouveau dans le monde C#/ASP.NET (je viens de java) et j'apprends pleins choses sympa!
Salut,
Pour ce qui est de logguer dans le journal, il y a des classes spécialisées pour ça dans le FrameWork.
Le singleton devrait être considéré comme une variable d'application. Les valeurs que les singleton mémorise sont disponibles pour l'ensemble de l'application. S'agissant de connections, à part provoquer des embouteillages, je vois pas l'intérêt.
Oui, mais, en créant un objet de connexion à chaque fois qu'on en a besoin on peut provoquer des dégats. Il faut absolument le faire dans des "using". Dans le cas contraire, on oublie de "Disposer" les objets et provoque une saturation du pool (dans le cas d'utilisation au sein de boucles).Citation:
Le framework s'occupe du reste. Il gére le pool de connexions, prend une connexion dispo quand il en a besoin, agrandit le pool si nécessaire...
Même dans des "using", la création d'objets de connexion provoque une élévation du nombre de connections par secondes. Ce n'est pas forcement un problème en soit, mais en général tous les pics sont des anomalies.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 public static void Select() { // Creation de la fabrique DbProviderFactory factory = DbProviderFactories.GetFactory(ConfigurationManager.ConnectionStrings["ChaineDeConnexion"].ProviderName); // Objet connection using (IDbConnection connection = factory.CreateConnection()) { connection.ConnectionString = ConfigurationManager.ConnectionStrings["ChaineDeConnexion"].ConnectionString; connection.Open(); // Objet Command using (IDbCommand command = factory.CreateCommand()) { command.CommandText = "SELECT * FROM usr_contract"; // Object datareader using (IDataReader reader = command.ExecuteReader()) { while (reader.Read()) { for (int i = 0; i < reader.FieldCount; i++) { if (reader[i] != DBNull.Value) Console.Write(reader[i].ToString()); else Console.Write("NULL"); if (i < reader.FieldCount) Console.Write("|"); } Console.WriteLine(); } } } } }
Personnellement, quand une de mes classes a besoin de se connecter à une base de données, je créé un objet de connection privé dont peut disposer toutes les méthodes de la classe. Cela impose de rendre ma classe disposable. Dans cet esprit, dans le code ci-dessus les objet "connection" et "command" seraient instanciés dans le constructeur de la classe (non statique du coup) et détruits dans la méthode "Dispose".
Ainsi, je profite du pool et n'augmente pas outrageusement le nombre de connections par secondes.
A+
Personnellement, dans l'envirronement asp.net, j'utilise tres souvent qu une seule base de donnée.J ai donc une classe page qui ouvre un connection sur le oninit et la ferme sur le onunload. Ainsi, si une classe a besoin d une connection lors de l'execution d'une page, elle en a une toute prete sans avoir a se preoccuper de quoi que ce soit.
Si je resume :
• Tu as une class static par exemple de connection à la BDD (ouverture/fermeture).
• Tu as une une class CommonPage dans laquelle dans le OnInit tu ouvres la connection et dans le onUnload tu fermes la connection.
• Toutes les pages web herite de CommonPage et pourront se servir de cette connection deja ouverte et sera fermé a chaque fois que tu changes de page.
C'est ca ?
Je n ai aps de classe statique. J'instancie un objet IDBConnection qui sera utilisé tout le long de l execution de la page et que je fermerais a la fermeture.
Je laisse .net gerer cette conenction dans le pool qu il veut. Tout ce que je sais c'Est que ma connection sera ouverte et fermé dans ma apge.
Les puristes retorqueront qu il faudrait simplement utiliser cette ouverture fermeture au plus pres du code qui utilise les données, et je ne les detromperais pas. Maintenant, je trouve ca aussi bien de n'instancier qu une seule fois mon objet IdbConnnection, en particulier lorsque beaucoup d'objet font appel a cette base de données dans ta page.
Encore une fois tout depend du contexte.
Ne pas utiliser d'objet statique me permet d'eviter tout probleme de lock et de concurrence, je n'y pense tout simplement pas.
Edit:
Oui j ai une classe statique ( je l avais oubliée celle la!)
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 /// <summary> /// Connection to the database of this application /// </summary> public IDbConnection ApplicationConnection { get { return MonObjetContext.GetConnection(); } set { MonObjetContext.SetConnection(value); } } protected override void OnInit(EventArgs e) { //create the connection to the Application Database and open it ApplicationConnection = DataProviderFactory.GetInstance().GetConnection(connectionstring); ApplicationConnection.Open(); base.OnInit(e); } protected override void OnUnload(EventArgs e) { if (ApplicationConnection != null) { //Close the connection to the Application Database and destroy it ApplicationConnection.Close(); ApplicationConnection.Dispose(); } base.OnUnload(e); }