Je rencontre un problème avec une condition de concurrence lors de l'enregistrement asynchrone dans la base de données en utilisant NHibernate. D'abord, une insertion dans la base de données est effectuée de manière asynchrone, où l'identifiant unique est généré automatiquement. Avant cette insertion revient au thread principal avec l'objet maintenant persisté qui a l'ID généré par base de données unique, l'objet dans la mise à jour d'une certaine manière. La mise à jour échouera si j'appelle session.Update car l'objet à mettre à jour n'a pas encore de valeur d'identifiant. Si j'appelle SaveOrUpdate, il en résultera évidemment une insertion au lieu d'une mise à jour car le champ id de mon entité est égal à la propriété non-value-value. Espérons que ce code rend la situation plus claire:Nhibernate, multithread et conditions de concurrence
Entity entity = new Entity()
//update some fields
entity.PropertyTwo = "new value";
//dataObject as the database auto-generated Id
//insert new row asynchronously in different thread
Entity entity.Id = dao.save(entity.Clone()).Id
//before the the entity is returned from the database, the entity might be updated
entity.Property = 'new value';
//entity might be sent without an Id since the first asynch call has not returned yet.
//update asynchronously in another thread
Object dataObject = dao.Update(entity); //fails because Id is not set yet
Une solution consiste à générer l'identifiant unique dans le code avant de sauvegarder. Dans ce cas, l'application gère l'incrémentation de l'identifiant unique par opposition à la base de données. D'autres façons de gérer cela?
Non Je crée une session par thread. La condition de concurrence survient si une mise à jour est mise à jour sur une entité avant la fin de l'insertion. – infinity
Gardez à l'esprit que chaque appel de base de données se produit sur un thread différent. Si une mise à jour est tentée sur un deuxième thread avant la fin de l'insertion. Erreur. – infinity
Pourriez-vous expliquer pourquoi vous clonez l'objet entité et enregistrez le clone? Vous avez peut-être déjà essayé cela, mais si vous faites SaveOrUpdate() dans tous vos threads pour le même objet entité (pas de clones), alors quel thread insère en premier, les autres feront des mises à jour. Est-ce que cela fonctionne pour votre conception? –