Lock optimistic; why not fire exception?

Asked

Viewed 105 times

4

I tried to simulate an optimistic Lock situation where one tries to update the same record twice, but the excesses are not triggered.

I find it interesting is that even after changing the value of the holder and giving a MERGE, the version value is not updated in the object nor in the database record.

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("financas");
    EntityManager em1 = emf.createEntityManager();
    EntityManager em2 = emf.createEntityManager();

    em1.getTransaction().begin();
    em2.getTransaction().begin();

    Conta c1 = em1.find(Conta.class,1);
    em1.lock(c1, LockModeType.OPTIMISTIC);
    em1.merge(c1);
    em1.getTransaction().commit();
    Conta c2 = em2.find(Conta.class,1);
    em2.lock(c2, LockModeType.OPTIMISTIC);
    em2.merge(c2);
    em2.getTransaction().commit();

------------- UPDATED ---------------------

Content of the class counts:

package br.com.financas.modelo;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Version;

@Entity
public class Conta {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    private String titular;
    private String banco;
    private String agencia;
    private String numero;

    @Version
    private int versao;

    public int getVersao() {
        return versao;
    }
    public void setVersao(int versao) {
        this.versao = versao;
    }
    @OneToMany(mappedBy="conta")
    private List<Movimentacao> movimentacoes;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getTitular() {
        return titular;
    }
    public void setTitular(String titular) {
        this.titular = titular;
    }
    public String getBanco() {
        return banco;
    }
    public void setBanco(String banco) {
        this.banco = banco;
    }
    public String getAgencia() {
        return agencia;
    }
    public void setAgencia(String agencia) {
        this.agencia = agencia;
    }
    public String getNumero() {
        return numero;
    }
    public void setNumero(String numero) {
        this.numero = numero;
    }
    public List<Movimentacao> getMovimentacoes() {
        return movimentacoes;
    }
    public void setMovimentacoes(List<Movimentacao> movimentacoes) {
        this.movimentacoes = movimentacoes;
    }


}

Why the exception is not cast?

  • Could you kindly make the source code of the Account class available.java?

  • The case you’re testing is the same one you put in here? In the example you put to your question, you do not make any changes to any attribute of Conta, in this way, no exception will be made.

1 answer

7


The exception is not made for two reasons:

1) No change has been made to the entity in either the first or the second context in which it was obtained and persisted, so there can be no conflict in the second context.

2) The transaction of the first context was completed (it was done commit) before the entity was obtained in the second context. So even if there was no problem 1, still there would be no exception as between the entity’s acquisition and persistence in the second context no change was made in another context.

For there to be an exception, the code needs to look something like this:

Conta c1 = em1.find(Conta.class,1);
em1.lock(c1, LockModeType.OPTIMISTIC);
c1.setNumero(novoNumero);       // linha adicionada
em1.merge(c1);
//em1.getTransaction().commit();   linha removida
Conta c2 = em2.find(Conta.class,1);
em2.lock(c2, LockModeType.OPTIMISTIC);
em1.getTransaction().commit();  // linha adicionada
c2.setNumero(aindaOutroNumero); // linha adicionada
em2.merge(c2);
em2.getTransaction().commit();

In the code above, the column version was updated and persisted after the entity was again obtained in another context. So when the entity is finally persisted in the other context, the value of version found in the database is different from that existing in the entity in memory, which will launch an exception of "the record was changed by another user".

Browser other questions tagged

You are not signed in. Login or sign up in order to post.