2009-06-19 5 views
0

J'utilise LINQ to SQL et j'ai un peu de problème à incrémenter une interconnexion de compteurs de vues.ChangeConflictException dans les mises à jour non simultanées de Linq à Sql

Le code tantinet j'utilise est:

t = this.AppManager.ForumManager.GetThread(id); 
t.Views = t.Views + 1; 
this.AppManager.DB.SubmitChanges(); 

maintenant dans mes tests, je cours ce à plusieurs reprises, non simultanément. Il y a un total de 4 copies de l'objet effectuant ce test. C'est-à-dire, il n'y a pas de problème de verrouillage, ou quelque chose comme ça, mais il y a 4 contextes de données.

Maintenant, je m'attendrais à ce que cela fonctionne comme ceci: récupérer une ligne, modifier un champ, mettre à jour la ligne. Cependant, cela lance une ChangeConflictException.

Pourquoi la modification serait-elle en conflit si aucune de ces copies ne s'exécute en même temps?

Existe-t-il un moyen d'ignorer les conflits de modification sur une table donnée?

EDIT: trouvé la réponse:

Vous pouvez définir « UpdateCheck = Jamais » sur toutes les colonnes sur une table pour créer un dernier en gagne le style de mise à jour. C'est ce que l'application utilisait avant de le porter sur LINQ, c'est ce que je vais utiliser pour le moment.

EDIT2: Alors que ma solution ci-dessus ne fait empêcher l'exception d'être jeté, il n'a pas résolu le problème sous-jacent:

Depuis que j'ai plus d'un contexte de données, il finit par être plus d'un cache copie de chaque objet. Dois-je recréer mon contexte de données avec chaque chargement de page? Je préférerais que le contexte de données oublie tout. Est-ce possible?

Répondre

2

Je crois que DataContext est en retrait pour être relativement léger et de courte durée. IMO, vous ne devez pas mettre en cache les données chargées avec un DataContext plus longtemps que nécessaire. Quand il est de courte durée, il reste relativement petit car (si je comprends bien) l'utilisation de la mémoire de DataContext est principalement associée au suivi des changements que vous faites aux objets gérés par lui (récupéré par lui).

Dans l'application sur laquelle je travaille, nous créons le contexte, affichons des données sur l'interface utilisateur, attendons les mises à jour de l'utilisateur, puis mettons à jour les données. Cependant, cela est nécessaire principalement parce que nous voulons que la mise à jour soit basée sur ce que l'utilisateur regarde (sinon nous pourrions récupérer les données et les mettre à jour toutes en même temps lorsque l'utilisateur clique sur la mise à jour). Si vos mises à jour sont relativement autonomes, je pense qu'il serait judicieux de récupérer la ligne immédiatement avant de la mettre à jour.

Vous pouvez également utiliser System.Data.Linq.DataContext.Refresh() pour resynchroniser les données déjà extraites avec les données de la base de données pour résoudre ce problème. Pour répondre à votre dernier commentaire sur le fait que le contexte oublie tout, je ne pense pas qu'il existe un moyen de le faire, mais je suppose que c'est parce que tout ce qu'il y a dans un contexte sont les changements suivis (et la connexion), et c'est tout aussi bien que vous créez un nouveau contexte (n'oubliez pas de vous débarrasser de l'ancien) parce que vous voulez vraiment jeter tout ce que le contexte est.