NHibernate ne lance pas d’exception StaleObjectStateException lorsque < Version > utilisé et données modifiées dans la base de données

StackOverflow https://stackoverflow.com/questions/1823445

Question

Une entité mappée dans NHibernate avec un contrôle d'accès concurrentiel optimiste utilise une colonne d'horodatage SQL comme numéro de version. Le mappage est le suivant:

<class name="Entity" optimistic-lock="version" discriminator-value="0">
    <id name="id">
        <generator class="native" />
    </id>
    <version name="Version" column="Version" generated="always" unsaved-value="null" type="System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    ...
    <subclass name="ChildEntity" discriminator-value="1" />
</class>

Je teste ce qui se passe lorsque les données d’une ligne de la base de données changent entre l’obtention et la mise à jour de l’enregistrement. Pour ce faire, j'exécute une instruction update directement sur l'un des enregistrements de la table en cours de mise à jour par NHibernate. Cette mise à jour directe modifie le numéro de version de l'enregistrement dans la table.

Comme prévu, la mise à jour gérée de NHibernate ne se produit pas sur la ligne en question (ce qui est une bonne chose). Cependant, aucune exception n'est levée lors de la validation. Je m'attendais à ce qu'une exception StaleObjectStateException se produise lors de la validation de la transaction afin de pouvoir l'annuler et d'informer l'utilisateur. N'est-ce pas le comportement attendu? Est-ce que je manque quelque chose?

Mon code pour valider la transaction ressemble à ceci:

_session.BeginTransaction();
...
// load objects in session
IList<ChildEntity> toChange = _session.Find('some condition');
foreach ( var itemToChange in toChange )
{
     itemToChange.Status = Status.Updated;
}
...
_session.Transaction.Commit();

Les éléments appartiennent à la même session et tout le travail est terminé au sein d'une seule transaction. ChildEntity est une sous-classe de la classe de base Entity, pour laquelle le verrou optimiste est défini sur la version.

Était-ce utile?

La solution 2

Il semble que mes tests étaient inexacts. Lors du test, je faisais le get APRÈS que l’autre transaction mette à jour l’enregistrement. Cette autre mise à jour a rendu la ligne inadmissible à la mise à jour. Aucune mise à jour n'a donc été tentée. Lorsque j'ai modifié le test pour effectuer la mise à jour concurrente APRÈS la commande Get, l'exception StaleObjectStateException a été levée comme prévu.

Désolé pour la confusion.

Autres conseils

Comment modifiez-vous les données? L'exception StaleObjectException est levée uniquement lorsque NHibernate tente de mettre à jour la ligne et que le numéro de version n'est plus le même. Les autres colonnes ne sont pas pertinentes. Est-il possible que lors de vos tests, vous ne mettiez pas à jour le numéro de version?

La prémisse est la suivante:

A. Utilisateur A & amp; B obtenir un objet de la base de données avec la version = 1

SQL: SELECT [objet] FROM [TABLE] où id = [id] et Version = 1

B. Utilisateur Un objet de mise à jour qui modifie la version en 2

SQL: UPDATE [TABLE] SET [objet] (& Set Version = 2) où id = [id] et Version = 1 renvoie 1 ligne mise à jour

.

C. L’utilisateur B tente de mettre à jour l’objet mais obtient une exception StaleObjectException en tant qu’objet update avec version = 1 (la version qu’il a obtenue étape 1) met à jour 0 enregistrements dans la base de données.

SQL: UPDATE [TABLE] SET [objet] où id = [id] et Version = 1 renvoie 0 ligne mise à jour et une exception StaleObjectException levée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top