Qual a diferença entre Lock OPTIMISTIC e PESSIMISTIC?

Pessoal… tenho pesquisado bastante na net, inclusive aqui no fórum, porém ainda tenho algumas dúvidas sobre Tratamento de Concorrência com JPA.
Ainda não conseguir ver a diferença entre os Dois.

No fórum encontrei um link de um breve tutorial, que diz:

[quote]Otimista - Quando é criado mecanismos para versionar o dado, no momento em que o banco vai efetivar sua operação sua versão é checada para garantir que você está com um dado que não foi alterado.

Pessimista - O banco simplesmente trava o dado e só aquele que tem a trava consegue trabalhar com os dados.[/quote]

Pelo que eu entendi, Otimista é quando vc usa o @version para controle de versão, e deixa que a implementação JPA cuide do resto

Quanto a Pessimista eu tenho algumas dúvidas, quando diz que o “banco trava o dado” qual é o scopodo dessa “trava”, posso travar um objeto, mandar ele pra interface e só esse usuário pode fazer alterações no mesmo e depois persistir? e quando outro processo for tentar persistir esse objeto que ta travado, ela vai dar a mensagem de erro??

ou

Eu só travo esse objeto entre o meu “transaction.begin()” até o meu “transaction.commit()”. Digamos que tenho um processo na minha camada de persistencia que leva um certo tempo para processar, e posso ter concorrencia com outros usuários, ai usaria esse tipo de lock?
Se sim, o meu lock Otmista tambem não ia cuidar disso? Imagina esse meu processo demorado, tenho uma concorrência nele, não será um processo por vez q vai chegar ao meu commit? e quando chegar o próximo processo o meu lock Otmista não vai propagar uma exceção?
Ou pode ocorrer de dois processos paralelos passarem no meu commit ao mesmo tempo?? e seria ai que o lock Pessimista entraria em ação?

Por favor, vi tem que um pessoal que conhece bem de Controle de concorrência aqui no fórum, quem puder me ajudar eu ficarei muito grato…

Bom, é isso… valew galera

1 curtida

UP!

O conceito de otimista/pessimista é baseado na probabilidade de acontecer a concorrencia. Ela vai sempre existir num sistema multi-usuario, distribuido,mas qual a probabilidade ?

por exemplo, qual a probabilidade de um usuario estar editando o cadastro do cliente ao mesmo tempo que outro usuário ?
Em algumas empressas essa probabilidade é quase zero ( nunca acredite que é realmente zero) então é um evento raro.

Otimista significa que vc acha que é um evento raro. Então um controle mais simples é suficiente. No hibernate/jpa vc usa o @Version

Pessimista significa que é muito provável (mais de x%) que o evento aconteça. E nesse caso usamos um esquema “pára tudo” onde não ha realmente concorrencia nenhuma.

A escolha não é apenas relativa à probabilidade, temos que atender ao risco e à performance. Um sistema pessimista é mais lento.

1 curtida

sergiotaborda,

Então lock PESSIMISTIC seria mais viável o uso em uma rotina onde exista vários acessos de vários usuário simultaneamente, onde o nível de concorrência é muito
alto?

Eu só ainda não consigo entender qual a diferença, vc não concorda comigo que mesmo que eu tivesse uma transação concorrente, por exemplo alterando o status de um
mesmo registro de uma tabela, uma não executaria primeira que a outra, alterando o CD_VERSION, e quando a outra transação fosse atualizar esse registro, o Lock Otimista
não entraria em ação??

Ou… é possível que duas transações, ao mesmo tempo, altere um registro e execute um commit no exato mesmo milisegundo?

[quote=diegopangone]sergiotaborda,

Então lock PESSIMISTIC seria mais viável o uso em uma rotina onde exista vários acessos de vários usuário simultaneamente, onde o nível de concorrência é muito
alto?

Eu só ainda não consigo entender qual a diferença, vc não concorda comigo que mesmo que eu tivesse uma transação concorrente, por exemplo alterando o status de um
mesmo registro de uma tabela, uma não executaria primeira que a outra, alterando o CD_VERSION, e quando a outra transação fosse atualizar esse registro, o Lock Otimista
não entraria em ação??
[/quote]

Não.
Não funciona assim.

Não é uma questão de tempo. É uma questão de isolamento.
Vc tem que tender melhor o modelo transacional para entender.

No modelo transacional, as transações são paralelas. mas o sistema, claro, só executa uma de cada vez (elas são threads, mas apenas uma thread está em execução num dado momento). O problema é que o sistema shifta entre threads, dando a cada uma uma chance de funcionar.
Portanto, não ha arantia que a primeira thread com a primeira transação a começar acabe antes das outras.

Esse conceito de uma transação é feita de cada vez não é real. Isso se conhece como serialização da transação (são feitas em série, uma depois da outra. e uma só começa quando a anterior termina. ) Este é o cenário pessimista. Cada transação executa sózinha, para não termos problema de concorrencia. Mas este modelo não escala. Para ter multi-threading temos que afrouxar o pessimismo.

Portanto é possivel que uma transação comece a alterar alguma coisa, seja interrompida, agora a outra transação mexe na mesma coisa, agora ela é interrompida, agora a transação inicial vai mexer… ups!.. os dados já não são coerentes…
Isto é isolamento. As transações precisam ser isoladas. O modo serial é perfeitamente isolado, mas não escala. Outros modos de transação com o banco são mais “soltas”.

O uso do campo version é controle de concorrencia pós transação. ou seja, as transações são ocurreram, mas seus dados são “velhos”. É um controle de “dirty” mais do que de transação. O problema que o version resolve pode acontecer mesmo com transações pessimistas perfeitamente serializadas.

1 curtida

sergiotaborda, Excelente explicação cara, deu pra clarear bem a minha idéia agora.

E olha vou te falar, pesquisando sobre lock, achei uma galera que é bem desinformada a respeito disso viu,
acredito que o tópico possa ajudar outros como eu.

Bom é isso… muito obrigado pela ajuda.

Abraço