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

VB.NET Discussion :

Cache qui mélange des données


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2018
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mai 2018
    Messages : 11
    Par défaut Cache qui mélange des données
    Bonjour tout le monde,

    Il m'arrive un problème vraiment très bizarre et aléatoire.
    J'ai un webService qui possède un module de cache (géré par un ConcurrentDictionary key/MemoryCache) pour gérer les objets génériques. Le cache fonctionne bien et ressort bien les données.

    Cependant je suis confronté à un bug vraiment bizarre que je n'arrive pas à comprendre ni à résoudre sans passer par le reset du cache.

    J'ai une liste de 4 objets très basiques que je requête en base (code / libellé, le code contient qu'une seule lettre). Je renvoie ensuite celui qui m'intéresse via une requête linq en singleOrDefault.
    J'ai une erreur qui pète aléatoirement sur le singleOrDefault car il trouve plus d'un élément qui matche. En investigant plus en détail, je me suis rendu compte qu'aléatoirement, en retournant chercher ma liste de 4 objets en cache, les lettres du codes se dupliquaient sur certains d'eux :

    J'ai 4 objets avec un code à "C", "R", "T" et "P", et un libellé bien distinct pour chaque, et aléatoirement le "T" se transforme en "R" (mais garde bien son libellé) et fait donc péter le Single fait derrière.
    Le seul moyen de résoudre le pb actuellement, c'est de rafraichir la liste en BDD, là les lettres se remettent bien et l'erreur disparait, jusqu'à un nouvel appel qui aléatoirement remélange mes codes...

    C'est tellement invraisemblable à mes yeux que j'espère que qqun aura une idée pour résoudre ce pb, sinon je mettrai un test d'unicité sur ma liste pour la rafraichir ou non, mais cette solution est moche et surtout j'ai peur que ce problème puisse arriver sur d'autres listes du cache.

    Merci d'avance,

    Guillaume

  2. #2
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    3 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 001
    Par défaut
    C'est assez confus.
    J'ai du relire plusieurs fois pour être certain de comprendre (et encore je ne suis pas sûr d'avoir compris).

    Au début j'ai cru que la clé du dictionnaire était ce fameux code.
    Et puis tu parles ensuite d'une liste de 4 objets dans le cache et j'en ai déduis que ton problème ne se situe pas sur le dictionnaire mais sur cette liste.
    Du coup c'est perturbant de mentionner ce dictionnaire...

    Je vais donc essayer de répondre au deux choses en ne sachant pas très bien ce qui te serviras.
    1 - Si la clé du dictionnaire est le code, alors cette clé ne peux pas changer sinon ça planterai ailleurs et donc la piste à suivre c'est que ce n'est pas le T qui se transforme en R mais le libellé du T qui change.
    2 - Si c'est dans la liste que ça se passe alors, tu dois avoir deux objets pointant sur la même adresse et change le contenu des deux en croyant n'en changer qu'un.

    Sans code, il est difficile te dire où se situe ton erreur.

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2018
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mai 2018
    Messages : 11
    Par défaut
    C'est vrai que c'était assez confus.

    Pour clarifier le dictionnaire comporte une clé (string) et un jeu de données (objet ou liste d'objets)

    Dans mon problème, c'est le jeu de données qui est en cause, donc pas de soucis du coté du dictionnaire.

    Les données ne sont jamais mises à jour dans le cache. C'est un cache temporaire de 10min, qui ne fait que de la lecture de base (il lit, il stocke pour 10min, et lorsqu'on refait une requête sur le jeu de données et que la clé existe en cache, on va chercher les données sur le cache).

    Le soucis, c'est que ce jeu de données change aléatoirement 1 fois sur 5, et pas n'importe comment, c'est toujours ma donnée au code "T" qui se transforme en code "R". Je pencherai donc plus sur un bug.

    A noter qu'en debug, la donnée est déjà corrompue dans le cache, ça ne vient pas d'un traitement fait par la suite.

    C'est vraiment très mystérieux...

  4. #4
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Billets dans le blog
    3
    Par défaut
    Poste ton code. Les explications c'est bien beau mais ca ne mene jamais bien loin.
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  5. #5
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Un objet dans un cache, à moins qu'il soit immutable, peut être modifié. Il suffit qu'il y ait des références qui traine dans un coin.

    Maintenant, comme précisé par DotNetMatt et popo, il nous faut du code pour comprendre le soucis. Au minimum :
    • le code chargeant le cache ;
    • le code raffraichissant le cache (si code différent) ;
    • le code utilisant le cache.

  6. #6
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2018
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mai 2018
    Messages : 11
    Par défaut
    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
    Private Property Caches As New ConcurrentDictionary(Of CacheCategory, MemoryCache)
    <ThreadStatic> Private SqlDataLayer As SQL_DataLayer
     
    Private ReadOnly Property Policy As CacheItemPolicy
            Get
                Return New CacheItemPolicy() With {.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(CInt(ConfigurationManager.AppSettings("TEMPS_CACHE")))}
            End Get
        End Property
     
        Private ReadOnly Property QuickPolicy As CacheItemPolicy
            Get
                Return New CacheItemPolicy() With {.AbsoluteExpiration = DateTimeOffset.UtcNow.AddSeconds(15)}
            End Get
        End Property
     
    Private Sub AddToCache(categorie As CacheCategory, key As String, value As Object, Optional quickCache As Boolean = False)
            If Cache_Active Then
                Try
                    If quickCache Then
                        Caches(categorie).Add(New CacheItem(key, value), QuickPolicy)
                    Else
                        Caches(categorie).Add(New CacheItem(key, value), Policy)
                    End If
                Catch ex As Exception
                End Try
           End If
    End Sub
     
    Private Function CacheContains(categorie As CacheCategory, key As String)
            If Cache_Active Then
                Try
                    If Caches(categorie).Contains(key) Then
                        Return True
                    End If
     
                    Return False
                Catch ex As Exception
                End Try
            Else
                Return False
            End If
        End Function
     
    Public Function Get_Dos_Collection(Of T)(Ctx As String, Optional Code As String = "") As IEnumerable(Of T)
            SqlDataLayer = New SQL_DataLayer
            Try
                Select Case GetType(T).Name.ToUpper
                    Case "Code_Etat"
                        Dim key As String = "Get_Dos_Collection_code_Etat"
                        If CacheContains(CacheCategory.Dossier, key) Then
                            Return Caches(CacheCategory.Dossier)(key)
                        Else
                            Dim retour = SqlDataLayer.GetAll_Code_Etat(Ctx)
                            AddToCache(CacheCategory.Dossier, key, retour)
                            Return retour
                        End If
                    Case ...........
                End Select
          Catch ex As Exception
          End Try
    End Function
     
     
    Public Function GetAll_Code_Etat(ByVal Contexte As String) As List(Of code_etat)
            Dim reader As DbDataReader = Nothing
            Dim Liste As New List(Of DOS_CODE_ETAT_DOSSIER)
     
            Try
                requete = "SELECT code, libelle, auto"
                requete &= " FROM code_etat"
                requete &= " ORDER BY libelle"
     
                reader = Ouverture_Reader()
     
                While reader.Read
                    Dim UnObj = New code_etat
                    UnObj.InitWithDataReader(reader, Contexte)
                    Liste.Add(UnObj)
                End While
            Catch ex As Exception
            Finally
                FermetureReader(reader, True)
            End Try
     
            Return Liste
     
        End Function

    D'avance désolé, je sais que c'est du VB mais c'est la même logique.
    Pour expliquer un peu plus, le CacheCategory est un énumerable de plusieurs catégories d'objets et le SQL_DataLayer est la classe qui gère les accès en BDD, j'ai mis un exemple avec une fonction d'appel en base pour que vous ayiez un topo complet.
    l'Ouverture_reader gère la commande et son execution en base et le InitWithDataReader sert juste à remplir les propriétés de l'objet.
    Je n'ai pas mis la gestion d'erreurs pour ne pas alourdir.

    Merci en tout cas,

    Guillaume

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 09/12/2007, 18h07
  2. script SQL qui réinsère des Données d'une BD dans une autre BD.
    Par kamaldev dans le forum Administration
    Réponses: 1
    Dernier message: 19/04/2007, 14h01
  3. Réponses: 1
    Dernier message: 26/11/2006, 10h57
  4. [JSP - JS] popup qui renvoie des données
    Par spk4ever dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 12/06/2006, 15h52
  5. [JSP] Pop up qui renvoie des données
    Par spk4ever dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 12/06/2006, 13h09

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