Domanda

Ho un'entità mappata in NHibernate con controllo di concorrenza ottimistico usando una colonna timestamp SQL come numero di versione. La mappatura è simile alla seguente:

<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>

Sto testando cosa succede quando i dati di fila nel database cambiano tra get e aggiornamento del record. Per fare ciò, sto eseguendo un'istruzione di aggiornamento direttamente su uno dei record nella tabella che sono in fase di aggiornamento da NHibernate. Questo aggiornamento diretto modifica il numero di versione del record nella tabella.

Come previsto, l'aggiornamento gestito NHibernate non si verifica sulla riga specifica (questo è buono). Tuttavia, non viene generata alcuna eccezione durante il commit. Mi aspettavo che si verificasse una StaleObjectStateException quando la transazione è stata commessa in modo da poter ripristinare la transazione e informare l'utente. Non è questo il comportamento previsto? Mi sto perdendo qualcosa?

Il mio codice per eseguire il commit della transazione è simile al seguente:

_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();

Gli articoli appartengono alla stessa sessione e tutto il lavoro è completato all'interno di una singola transazione. ChildEntity è una sottoclasse della classe base Entity, che ha il blocco ottimistico impostato su versione.

È stato utile?

Soluzione 2

Sembra che i miei test non siano accurati. Nel test, stavo facendo il get dopo che l'altra transazione ha aggiornato il record. Questo altro aggiornamento ha reso la riga non idonea per l'aggiornamento, quindi non è stato tentato alcun aggiornamento. Quando ho modificato il test per eseguire l'aggiornamento della concorrenza DOPO Get, quindi StaleObjectStateException è stata generata come previsto.

Ci scusiamo per la confusione.

Altri suggerimenti

Come stai modificando i dati? StaleObjectException viene generato solo quando NHibernate tenta di aggiornare la riga e il numero di versione non è più lo stesso. Le altre colonne sono irrilevanti. È possibile che durante i test non stia aggiornando il numero di versione?

La premessa è questa:

A. Utente A & amp; B ottiene l'oggetto dal database con versione = 1

SQL: SELEZIONA [oggetto] DA [TABELLA] dove id = [id] e Versione = 1

B. Utente A Oggetto Aggiorna che modifica la versione in 2

SQL: UPDATE [TABLE] SET [object] (& amp; Set Version = 2) dove id = [id] e Version = 1 restituisce 1 riga aggiornata

C. L'utente B tenta di aggiornare l'oggetto ma ottiene StaleObjectException come oggetto di aggiornamento con version = 1 (la versione ha ottenuto il passaggio 1) aggiorna 0 record nel database.

SQL: UPDATE [TABLE] SET [oggetto] dove id = [id] e Version = 1 restituisce 0 righe aggiornate e viene generata StaleObjectException.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top