2009-02-06 7 views
3

Je travaille sur une grande application qui gère des 'événements' complexes avec beaucoup de données.Plusieurs sauvegardes simultanées provoquent WCF/NHibernate "Ligne mise à jour par une autre transaction"

L'application est cassée dans un client (C# principalement. NET 2.0 principalement), un serveur basé sur WCF fait pour fonctionner sur IIS (services Web à cette couche), et un backend de données qui est NHibernate basé sur MS SQL Backend de base de données du serveur.

nous rencontrons un bug avec le scénario de suivi:

utilisateurs multiples (dans ce cas 6, lors de nos tests) enregistrer simultanément un objet persistant (comme un événement) sur le client. (Cela se fait via un compte à rebours verbal, donc nous parlons d'une seconde différence à cause des temps de réaction)

Lorsqu'ils sauvegardent des objets sur le client, le client appelle le serveur pour enregistrer cet objet. Le serveur effectue toute la logique métier requise, puis valide la modification via NHibernate.

Dans cette situation (multiple permet d'économiser sur les appels de service) certains clients vont revenir à l'exception unhanded:

"Row a été mis à jour ou supprimé par une autre transaction"

Ce qui est une exception NHibernate.

Dans mes recherches, j'ai trouvé quelques exemples de cette erreur, mais c'était toujours séquentiel. Notre application est très bien séquentiellement, cela ne se produit qu'avec des sauvegardes simultanées.

Comment plusieurs transactions NHibernate simultanées doivent-elles être protégées les unes des autres?

(Cela va être une application à haut volume, si minime verrouillage nécessaire est bon. Nous ne pouvons pas nous permettre de verrouiller tous les arrêts en général.)

Y at-il des paramètres NHibernate qui le faire? Avons-nous besoin de comprendre le verrouillage du côté du code serveur avant la main? La base de données peut-elle gérer cela avec peut-être des paramètres de protection des transactions différents?

Ceci est un ours à tester, comme la plupart des problèmes de threading, d'où l'approche de recherche/théorie. Quelle est l'expérience avec une architecture comme celle-ci?

Edit: Plus d'informations et une théorie.

Il semble que le fait de changer les valeurs qui sont directement dans la table en tant qu'entité principale n'a pas causé ce problème, tout en changeant les éléments qui sont accessibles via une jointure. (Dans ce cas, un ensemble d'attributs).

Notre théorie de travail qui semble correspondre à cette situation est la suivante:

Multiple venir pour enregistre le même événement. Chacun reçoit une copie de l'événement existant (à modifier). Les premiers à enregistrer sont OK. Les derniers, cependant, ont des mises à jour telles que l'ajout ou la suppression d'attributs (qui sont une table de jointure) et découvrent que l'ajout ou la suppression a déjà été fait et se termine parce qu'une autre transaction a modifié l'événement.

Comment devrions-nous synchroniser ces événements?

Répondre

1

J'ai eu le même problème avec une application utilisateur unique qui était multithread. La clé consistait à décorer ma variable de session avec [ThreadSafe].Bizarrement, les différents gestionnaires de session que j'ai regardés ne semblent pas faire cela, et ils estiment qu'ils sont thread safe automatiquement ... n'était pas le cas dans mon expérience.

Asp Session Manager

Multi DB Session

1

j'ai accepté la réponse ci-dessus parce qu'il était plus ou moins la route, nous sommes allés avec. Je voulais élaborer plus loin. Notre application est destinée à être utilisée intensivement, donc le verrouillage d'une procédure de 'mise à jour d'une entité majeure' est une mauvaise idée. Ce que nous avons fini par faire était d'utiliser le mutex C# qui prenait "quelque chose d'unique" à verrouiller, dans ce cas un ID d'événement. Cela signifie que toutes les opérations sur la même entité complexe seraient verrouillées et deviendraient «atomiques» dans ce sens. Cela a réglé notre problème. Nous avons enveloppé plus ou moins chaque opération de service «destructrice» dans un mutex (via une classe d'utilitaires existante).

Questions connexes