ti-enxame.com

Manipulação de atualizações simultâneas no hibernate

Atualmente, estamos usando o JDBC na camada de dados e planejando substituí-lo por hibernação. Eu sou novo no Hibernate e não tenho certeza de como o hibernate lida com a simultaneidade. Alguém pode me explicar se usarmos spring para o gerenciamento de transações, como as atualizações simultâneas serão tratadas: pelo hibernate (na memória, gerenciamento automático de versões do hibernate) ou eu tenho que colocar a coluna version no banco de dados para cuidar das atualizações simultâneas manualmente.

23
Rakesh Goyal

Alguém pode me explicar se usarmos spring para o gerenciamento de transações, como as atualizações simultâneas serão tratadas pelo hibernate (na memória, gerenciamento automático de versões do hibernate) ou eu tenho que colocar a coluna version no banco de dados para cuidar das atualizações simultâneas manualmente.

Se você está usando o Spring para gerenciamento de transações ou não, realmente não importa e não é relevante quando se trata de gerenciamento de concorrência, isso é realmente tratado pelo Hibernate. O Hibernate pode usar duas estratégias para lidar com atualizações simultâneas: bloqueio otimista e bloqueio pessimista.

Otimista

Ao usar o bloqueio otimista, você mapeia um atributo especial (um número, um carimbo de data/hora) como versão (para que você realmente tenha uma coluna para ele). Esta versão é lida quando você recupera uma entidade e incluído na cláusula where durante uma atualização e incrementada pelo Hibernate.

Para ilustrar como isso funciona, vamos imaginar que você carregue uma entidade Person por id = 1 e com uma versão atual = 1. Após salvar, o Hibernate executará algo como isto:

update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;

Então, agora, imagine que você tenha duas transações simultâneas em execução, cada uma carregando a entidade mesma (mesmo número de versão) e alterando o nome.

Digamos que a transação nº 1 seja confirmada primeiro, a seguinte consulta é realizada:

update PERSON set ID=1, NAME='NAME 1', VERSION=2 where ID=1 and VERSION=1;

É bem-sucedido e a versão é incrementada.

Em seguida, a transação 2 é confirmada, a seguinte consulta é realizada:

update PERSON set ID=1, NAME='NAME 2', VERSION=2 where ID=1 and VERSION=1;

Este não atualizará nada porque a cláusula where não corresponderá a nenhum registro. É aqui que você obtém uma exceção de simultaneidade otimista.

Essa estratégia é apropriada quando você não mantém a conexão, quando acessos simultâneos não são frequentes e dimensiona muito bem. E é claro que tudo é tratado de forma transparente pelo Hibernate para você, desde que você mapeie um atributo de versão.

Pessimista

Ao usar o bloqueio pessimista, o Hibernate bloqueia um registro para seu uso exclusivo até você terminar com ele (normalmente usando um SELECT ... FOR UPDATE). Qualquer outra transação simultânea que tente acessar o mesmo registro será suspensa até que o bloqueio seja removido. Essa estratégia oferece melhor previsibilidade, ao preço do desempenho e não é escalável indefinidamente.

Referências

56
Pascal Thivent

Existem implementações de JPA como o objectDB nas quais o bloqueio otimista é ativado por padrão e o usuário não precisa manter a variável de versão na tabela do banco de dados, pois ele é tratado internamente pelo objectDB. O bloqueio otimista é bom quando as atualizações não são frequentes e onde o bloqueio tem custos implícitos, como no comércio eletrônico, onde o bloqueio significa perda de negócios. O bloqueio pessimista é ideal quando a concorrência não é muito exigida e a transação é concluída rapidamente para liberar o recurso.

1
Chaitan Yadav

Existem algumas documentação sobre sessões e transações no wiki da comunidade Hibernate . No fim das contas, ele é tratado pelas transações subjacentes do RDBMS, mas você precisa prestar atenção ao ciclo de vida dos objetos carregados ou salvos.

0
Bruno