IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ASP.NET Discussion :

[Singleton] Class SQL qui fait planté le serveur


Sujet :

ASP.NET

  1. #1
    Membre confirmé

    Homme Profil pro
    Développeur Java
    Inscrit en
    février 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2007
    Messages : 179
    Points : 649
    Points
    649
    Par défaut [Singleton] Class SQL qui fait planté le serveur
    Bonjour,

    Je me trouve devant un problème que je n'arrive pas a résoudre depuis quelques mois.
    J'ai une classe SQL (ci-dessous), je l'ai écrite selon un design pattern singleton.
    Mais le problème c'est qu'on dirait qu'au bout de 5 construction d'objet le serveur plante.
    Je pense que c'est parce qu'il ne me détruit pas mon objet a la fin du script (l'exception est la pour le vérifié), mais il ne le récupère pas lors de l'appel d'une autre page, donc j'ai plusieurs connexion SQL simultané et puis ca doit planté a cause de ça.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    Imports Microsoft.VisualBasic
    Imports System.Data.SqlClient
    Public Class SQL
    	Private Shared instance As SQL = Nothing
     
    	Private strConnection As String = Nothing
    	Private connection As SqlConnection = Nothing
    	Private errorMessage As String = Nothing
     
    	Public Shared Function getInstance(ByVal strconnect As String) As SQL
    		If instance Is Nothing Then
    			instance = New SQL(strconnect)
    			instance.connect()
    		End If
    		Return instance
    	End Function
     
    	Public Shared Function getInstance() As SQL
    		If instance Is Nothing Then
    			instance = New SQL()
    		End If
    		Return instance
    	End Function
     
    	Private Sub New()
    		Throw New Exception("on fait le new")
    		Me.strConnection = "Data Source=.\SQLEXPRESS;AttachDbFilename=""C:\Documents and Settings\***\BDD.mdf"";Integrated Security=True;Connect Timeout=30;User Instance=True"
    	End Sub
     
    	Private Sub New(ByVal strConnect As String)
    		Me.strConnection = strConnect
    	End Sub
     
    	Private Function connect() As Boolean
    		If Me.strConnection Is Nothing Then
    			Throw New Exception("La chaine de connexion n'a pas été spécifié")
    		End If
    		If Me.connection Is Nothing Then
    			Try
    				Me.connection = New SqlConnection(Me.strConnection)
    				Me.connection.Open()
    			Catch ex As Exception
    				System.Diagnostics.Debug.WriteLine(ex.ToString()) 'On écrit dans le stream de débug
    				Me.errorMessage = ex.Message
    				Return False
    			End Try
    		End If
    		Return True
    	End Function
     
    	Private Function disconnect() As Boolean
    		If Not Me.connection Is Nothing Then
    			Try
    				Me.connection.Close()
    				Me.connection.Dispose()
    				Me.connection = Nothing
    				Me.errorMessage = Nothing
    			Catch ex As Exception
    				System.Diagnostics.Debug.WriteLine(ex.ToString()) 'On écrit dans le stream de débug
    				Me.errorMessage = ex.Message
    				Return False
    			End Try
    			Return True
    		End If
    		Return False
    	End Function
     
    	Public Function getError() As String
    		Return Me.errorMessage
    	End Function
     
    	Public Function query(ByVal strQuery As String) As ArrayList
    		'...
    		Return new ArrayList()
    	End Function
     
    	Public Function execute(ByVal strQuery As String) As Integer
    		'...
    		Return 0
    	End Function
     
    	Protected Overrides Sub Finalize()
    		Throw New Exception("On fait finalize")
    		Me.disconnect()
    		Me.strConnection = Nothing
    		MyBase.Finalize()
    	End Sub
    End Class
    L'expérience est une lanterne que l'on porte sur le dos et qui n'eclaire jamais que le chemin parcouru.

    La nature fait les choses sans se presser, et pourtant tout est accompli.

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    avril 2008
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2008
    Messages : 35
    Points : 41
    Points
    41
    Par défaut
    SQl express edition ne sait pas gérér plus de 5 connections simultanées.

    Je te conseille de simplifier ta class SQL, et d'ouvrir une connection , faire un traitement et fermer la connection dans la foulée.

    Inspire toi de ca si ca peut t'aider :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
     Public Function OpenSql() As SqlConnection
            Try
                Dim scConnect As SqlConnection = New SqlConnection()
                Dim server As String
                Dim database As String
                Dim auth As String
                Dim userID As String
                Dim password As String
                Dim connectionString As String
     
     
                server = My.Settings.serveur.ToString    'settings de l'application - paramètres appli
                database = My.Settings.database.ToString
                auth = My.Settings.authentification.ToString
                userID = My.Settings.userID.ToString
                password = My.Settings.password.ToString
     
     
                connectionString = "Data Source=" & server & ";initial catalog=" & database & _
                                   ";Integrated Security=" & auth & ";user id=" & userID & ": pwd = " & password & ";"
     
                scConnect.ConnectionString = connectionString
     
                scConnect.Open()
                If scConnect.State = ConnectionState.Open Then
                    Return scConnect
                Else
                    Return Nothing
                End If
            Catch ex As Exception
                Return Nothing
            End Try
        End Function
     
        Public Sub SqlClose(ByRef scConnect As SqlConnection) 'PAssage par adresse préférable à passage par valeur ici
            'fermeture connection sql
            If scConnect.State.Equals(ConnectionState.Open) Then
                scConnect.Close()
            End If
            scConnect.Dispose()
        End Sub
     
    Public Function ExeRequeteMAJ(ByVal requete As String) As Integer
            'Exécute la requête INSERT, UPDATE ou DELETE et retourne le nombre de lignes affectées
            Try
                Dim scConnect As SqlConnection = OpenSql()
                Dim cmdCommandMAJ As New SqlCommand
                Dim NbLignes As Integer = 0
     
                cmdCommandMAJ.CommandText = requete
                cmdCommandMAJ.Connection = scConnect
                NbLignes = cmdCommandMAJ.ExecuteNonQuery()
                SqlClose(scConnect)
                Return NbLignes
            Catch Err As System.Exception
                Return -1
            End Try
        End Function

    si je dis pas de betise (les modos ?) la destruction d'objets est géré par le garbage collector.......
    A mon avis c'est lié a ton nombre de connections ouvertes , et non a la destruction de ton objet

  3. #3
    Membre confirmé

    Homme Profil pro
    Développeur Java
    Inscrit en
    février 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2007
    Messages : 179
    Points : 649
    Points
    649
    Par défaut
    Citation Envoyé par Lefaucheux Voir le message
    SQl express edition ne sait pas gérér plus de 5 connections simultanées.

    Je te conseille de simplifier ta class SQL, et d'ouvrir une connection , faire un traitement et fermer la connection dans la foulée.
    C'est justement ce que je veux évité parce que ouvrir une connexion et puis passé l'objet dans toutes les class c'est chiant ou bien ouvrir un connexion a chaque fois c'est impensable parce que j'aurais trop d'ouverture (ce qui prend le plus de temps).


    Citation Envoyé par Lefaucheux Voir le message
    si je dis pas de betise (les modos ?) la destruction d'objets est géré par le garbage collector.......
    A mon avis c'est lié a ton nombre de connections ouvertes , et non a la destruction de ton objet
    Justement le garbage collector devrait appeler mon destructeur qui lui ferme la connexion avec la base de donnée.
    L'expérience est une lanterne que l'on porte sur le dos et qui n'eclaire jamais que le chemin parcouru.

    La nature fait les choses sans se presser, et pourtant tout est accompli.

  4. #4
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Le destructeur (Finalize) ne sert pas à faire ça. Le garbage collector est fait pour se charger de la libération de la mémoire. Implémente plutôt le pattern Dispose.

    Pour la gestion des connexions à la base, la méthode recommandée est d'ouvrir la connexion le plus tard possible et de la refermer le plus tôt possible.
    Cela évite les problèmes de "starvation" et permet de laisser le connection pool faire son travail.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  5. #5
    Membre confirmé

    Homme Profil pro
    Développeur Java
    Inscrit en
    février 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2007
    Messages : 179
    Points : 649
    Points
    649
    Par défaut
    Citation Envoyé par SaumonAgile Voir le message
    Le destructeur (Finalize) ne sert pas à faire ça. Le garbage collector est fait pour se charger de la libération de la mémoire. Implémente plutôt le pattern Dispose.
    Je viens de me renseigné sur le Design pattern Dispose, on donne juste la possibilité a l'utilisateur d'objet de libéré les ressources avec le garbage collector, cela pourrait me permettre d'enlever l'erreur.
    Mais alors pourquoi le garbage collector, alors que dans le finalize je coupe la connexion, garde la connexion ?
    Est-ce a cause du design pattern singleton qui garde une référence sur l'objet, et à la fin du script il le détruit pas cette shared variable et donc n'appelle pas le destructeur.

    Merci de m'avoir aiguillé vers le pattern dispose mais j'aimerais bon comprendre pourquoi le garbage collector ne me détruit pas l'objet...

    P.S. : Je suis parfaitement d'acore en ce qui concerne la connexion SQL mais je pense qu'il faut évité la 10 connexion dans le même script.1 seule suffi même si elle est ouverte un peu trop longtemps.
    L'expérience est une lanterne que l'on porte sur le dos et qui n'eclaire jamais que le chemin parcouru.

    La nature fait les choses sans se presser, et pourtant tout est accompli.

  6. #6
    Modérateur

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    avril 2007
    Messages
    1 996
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Service public

    Informations forums :
    Inscription : avril 2007
    Messages : 1 996
    Points : 3 102
    Points
    3 102
    Par défaut
    Je ne suis pas un expert mais j'aurais tendance à te répondre que le Garbage Collector est bien gentil mais fait ce qu'il veut!
    Autrement dit, si je me rappelle bien de mes cours sur le framework, le GC ne passe que quand il l'a décidé ou quand un besoin de mémoire se fait sentir.

  7. #7
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    La propriété instance conserve toujours une référence vers l'objet, donc le GC ne détruira jamais cette instance.
    Tu n'as pas besoin d'un singleton. Et comme je t'ai dit avant, le pool de connexion se charge d'ouvrir et fermer "réellement" les connexions que tu utilises. Il garde des connexions ouvertes en interne pour éviter de faire des ouvertures/fermetures couteuses en terme de performance.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Requête qui fait ramer le serveur
    Par Théolude dans le forum Requêtes
    Réponses: 8
    Dernier message: 09/02/2010, 10h26
  2. fonction qui fait crasher le serveur ?
    Par hannibal69 dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 19/04/2007, 17h00
  3. Requete qui fait planter le serveur.
    Par Lambrosx dans le forum Installation
    Réponses: 6
    Dernier message: 05/04/2007, 19h28
  4. Réponses: 3
    Dernier message: 27/01/2007, 10h11
  5. qui fait le travail ? serveur ou client??
    Par lykim dans le forum Applets
    Réponses: 31
    Dernier message: 16/05/2006, 17h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo