Pergunta

Eu tenho uma entidade mapeada em NHibernate com controle de concorrência otimista usando uma coluna SQL timestamp como o número da versão. O mapeamento é como o seguinte:

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

Estou testando o que acontece quando os dados em uma fila nas mudanças de banco de dados entre o get ea atualização do registro. Para fazê-lo, estou executando uma instrução de atualização diretamente contra um dos registros na tabela que estão em vias de ser atualizado por NHibernate. Esta atualização direta muda o número da versão do registro na tabela.

Como esperado, a atualização NHibernate conseguiu não ocorre na linha específica (isso é bom). No entanto, nenhuma exceção é lançada durante a cometer. Eu esperava um StaleObjectStateException a ocorrer quando a transação foi confirmada para que eu pudesse reverter a transação e informar o usuário. Não é este o comportamento esperado? Estou faltando alguma coisa?

Meu código para confirmar a transação é algo como isto:

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

Os itens pertencem à mesma sessão e todo o trabalho é concluído dentro de uma única transação. ChildEntity é uma subclasse da classe base Entity, que tem o definido para a versão optimistic-lock.

Foi útil?

Solução 2

Parece que o meu teste foi impreciso. No teste, eu estava fazendo a começar depois a outra transação atualizou o registro. Esta outra atualização feita a inelegível linha para a atualização, por isso não atualização foi tentada. Quando eu mudei o teste para fazer a atualização competindo DEPOIS do Get, em seguida, o StaleObjectStateException foi lançada como esperado.

Desculpe pela confusão.

Outras dicas

Como você está modificando os dados? O StaleObjectException é lançada apenas quando tentativas NHibernate para atualizar a linha eo número da versão não é mais o mesmo. As outras colunas são irrelevantes. É possível que em sua testando você não está atualizando o número da versão?

A premissa é esta:

A. Usuário A & B obter objeto de banco de dados com versão = 1

SQL: SELECT [object] FROM [TABLE] where id = [id] and Version = 1

B. Um usuário do Updates objeto que muda a versão de 2

SQL: UPDATE [TABLE] SET [object] (& Set Version = 2) where id = [id] and Version = 1 retorna 1 linha atualizada

C. Usuário B tentativas para objeto de atualização, mas fica StaleObjectException como objeto de atualização com a versão = 1 (a versão que ele conseguiu passo 1) atualiza 0 registros no banco de dados.

SQL:. UPDATE [TABLE] SET [object] where id = [id] and Version = 1 retorna 0 linhas atualizado e StaleObjectException jogado

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top