De tempos em tempos, ISession
ele executa as instruções SQL necessárias para sincronizar o estado da conexão ADO.NET com o estado dos objetos mantidos na memória. Esse processo, liberado, ocorre por padrão nos seguintes pontos
- de algumas invocações de
Find()
ouEnumerable()
- de
NHibernate.ITransaction.Commit()
- de
ISession.Flush()
As instruções SQL são emitidas na seguinte ordem
- todas as inserções de entidade, na mesma ordem em que os objetos correspondentes foram salvos usando
ISession.Save()
- todas as atualizações da entidade
- todas as exclusões de coleção
- todas as exclusões, atualizações e inserções de elementos de coleção
- todas as inserções de coleção
- todas as exclusões de entidades, na mesma ordem em que os objetos correspondentes foram excluídos usando
ISession.Delete()
(Uma exceção é que os objetos que usam geração de ID nativa são inseridos quando são salvos.)
Exceto quando você explica Flush()
, não há absolutamente nenhuma garantia sobre quando a Sessão executa as chamadas do ADO.NET, apenas a ordem em que elas são executadas . No entanto, o NHibernate garante que os ISession.Find(..)
métodos nunca retornarão dados obsoletos; nem retornarão os dados errados.
É possível alterar o comportamento padrão para que a liberação ocorra com menos frequência. A FlushMode
classe define três modos diferentes: liberar apenas no momento da confirmação (e somente quando a ITransaction
API NHibernate é usada), liberar automaticamente usando a rotina explicada ou nunca liberar, a menos que Flush()
seja chamado explicitamente. O último modo é útil para unidades de trabalho de execução longa, onde um ISession
é mantido aberto e desconectado por um longo período de tempo.
...
O encerramento de uma sessão envolve quatro fases distintas:
- liberar a sessão
- confirmar a transação
- fechar a sessão
- lidar com exceções
Liberando a Sessão
Se você estiver usando a ITransaction
API, não precisará se preocupar com esta etapa. Isso será realizado implicitamente quando a transação for confirmada. Caso contrário, você deve ligar ISession.Flush()
para garantir que todas as alterações sejam sincronizadas com o banco de dados.
Confirmando a transação do banco de dados
Se você estiver usando a API do NHibernate ITransaction, será semelhante a:
tx.Commit(); // flush the session and commit the transaction
Se você estiver gerenciando as transações do ADO.NET, deverá manualmente Commit()
a transação do ADO.NET.
sess.Flush();
currentTransaction.Commit();
Se você decidir não confirmar suas alterações:
tx.Rollback(); // rollback the transaction
ou:
currentTransaction.Rollback();
Se você reverter a transação, feche e descarte a sessão atual imediatamente para garantir que o estado interno do NHibernate seja consistente.
Fechando a ISession
Uma chamada para ISession.Close()
marcar o final de uma sessão. A principal implicação de Close () é que a conexão ADO.NET será abandonada pela sessão.
tx.Commit();
sess.Close();
sess.Flush();
currentTransaction.Commit();
sess.Close();
Se você forneceu sua própria conexão, Close()
retorna uma referência a ela, para que você possa fechá-la manualmente ou devolvê-la ao pool. Caso contrário, Close()
ele será retornado à piscina.
A partir do NHibernate 2.0, as transações são necessárias para operações do banco de dados. Portanto, a
ITransaction.Commit()
chamada tratará de qualquer descarga necessária. Se, por algum motivo, você não estiver usando transações do NHibernate, não haverá liberação automática da sessão.fonte
Periodicamente, o ISession executará as instruções SQL necessárias para sincronizar o estado da conexão ADO.NET com o estado dos objetos mantidos na memória.
E sempre use
depois que as alterações são confirmadas, essas alterações são salvas no banco de dados e usamos transaction.Commit ();
fonte
Aqui estão dois exemplos do meu código em que ele falharia sem session.Flush ():
http://www.lucidcoding.blogspot.co.uk/2012/05/changing-type-of-entity-persistence.html
No final, você pode ver uma seção de código em que eu ativo a inserção de identidade, salve a entidade e, em seguida, libero, e desative a inserção de identidade. Sem essa liberação, parecia estar ativando e desativando a inserção de identidade e salvando a entidade.
O uso de Flush () me deu mais controle sobre o que estava acontecendo.
Aqui está outro exemplo:
Enviando mensagem NServiceBus dentro do TransactionScope
Eu não entendo completamente o porquê, mas Flush () impediu que meu erro acontecesse.
fonte