NHibernate no lanza StaleObjectStateException cuando < Version > utilizado y datos modificados en la base de datos

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

Pregunta

Tengo una entidad asignada en NHibernate con control de concurrencia optimista utilizando una columna de marca de tiempo SQL como número de versión. El mapeo es como el siguiente:

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

Estoy probando qué sucede cuando los datos en una fila de la base de datos cambian entre la obtención y la actualización del registro. Para hacerlo, estoy ejecutando una declaración de actualización directamente en uno de los registros de la tabla que NHibernate está actualizando. Esta actualización directa cambia el número de versión del registro en la tabla.

Como se esperaba, la actualización administrada de NHibernate no ocurre en la fila específica (esto es bueno). Sin embargo, no se produce ninguna excepción durante la confirmación. Esperaba que se produjera una StaleObjectStateException cuando se confirmó la transacción para poder revertir la transacción e informar al usuario. ¿No es este el comportamiento esperado? ¿Me estoy perdiendo algo?

Mi código para confirmar la transacción se ve así:

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

Los elementos pertenecen a la misma sesión y todo el trabajo se completa dentro de una sola transacción. ChildEntity es una subclase de la clase base Entidad, que tiene el bloqueo optimista establecido en la versión.

¿Fue útil?

Solución 2

Parece que mi prueba fue inexacta. En la prueba, estaba obteniendo DESPUÉS de que la otra transacción actualizara el registro. Esta otra actualización hizo que la fila no fuera elegible para la actualización, por lo que no se intentó ninguna actualización. Cuando cambié la prueba para hacer la actualización de la competencia DESPUÉS de Get, entonces se lanzó la StaleObjectStateException como se esperaba.

Perdón por la confusión.

Otros consejos

¿Cómo está modificando los datos? StaleObjectException se produce solo cuando NHibernate intenta actualizar la fila y el número de versión ya no es el mismo. Las otras columnas son irrelevantes. ¿Es posible que en sus pruebas no esté actualizando el número de versión?

La premisa es esta:

A. Usuario A & amp; B obtener objeto de la base de datos con version = 1

SQL: SELECT [object] FROM [TABLE] donde id = [id] y Version = 1

B. El usuario A actualiza el objeto que cambia la versión a 2

SQL: UPDATE [TABLE] SET [objeto] (& amp; Set Version = 2) donde id = [id] y Version = 1 devuelve 1 fila actualizada

C. El usuario B intenta actualizar el objeto, pero obtiene StaleObjectException como objeto de actualización con version = 1 (la versión que obtuvo, paso 1) actualiza 0 registros en la base de datos.

SQL: UPDATE [TABLE] SET [objeto] donde id = [id] y Version = 1 devuelve 0 filas actualizadas y se produce StaleObjectException.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top