Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

448
Visualizações
Hibernate: bloquea una fila durante la actualización, para que el usuario no recupere un contador de ella

Estoy trabajando en un proyecto Spring-MVC en el que estoy usando Hibernate como ORM, PostgreSQL como nuestra base de datos y en uno de nuestros Objetos (GroupCanvas), tenemos un número que se incrementa cada vez que el usuario realiza alguna acción, y luego el El objeto GroupCanvas se actualiza en la base de datos y debe ser único.

El problema que tenemos actualmente es que, si varios usuarios toman medidas en el front-end, algunos de ellos obtienen números duplicados. Estamos trabajando para arreglar esto ahora, para que luego podamos implementar una secuencia y estar seguros de que los números son únicos.

¿Cómo puedo asegurarme de que cuando estoy actualizando la fila, otros usuarios estén esperando hasta que se actualice la fila? Probé LockMode.Pessimistic_write, y algunos otros, ninguno ayudó.

Código:

 @Override public void incrementNoteCounterForGroupCanvas(int canvasId) { Session session = this.sessionFactory.getCurrentSession(); session.flush(); Query query = session.createQuery("update GroupCanvas as gc set gc.noteCount=gc.noteCount+1 where gc.mcanvasid=:canvasId"); query.setParameter("canvasId",canvasId); query.executeUpdate(); session.flush(); } @Override public GroupCanvas getCanvasById(int mcanvasid) { Session session = this.sessionFactory.getCurrentSession(); session.flush(); return (GroupCanvas) session.get(GroupCanvas.class, mcanvasid,LockMode.PESSIMISTIC_WRITE); }

Ambos métodos están en DAO, que tiene anotación @Transactional y anotación presente en la capa de servicio también.

Gracias.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Mirando el método que ha publicado el uso si la técnica de 'BLOQUEO' no es del todo correcta. Para que un bloqueo termine con el resultado que está buscando, la secuencia de acciones debe ser similar a las siguientes (en pocas palabras, es similar al bloqueo de doble verificación pero implementado mediante bloqueos DB - https://en .wikipedia.org/wiki/Double-checked_locking ).

  1. Inicie la transacción (por ejemplo, anotación @Transactional en su método de servicio)
  2. Recupere la entidad de la base de datos con el modo de bloqueo PESSIMISTIC_WRITE (asegúrese de indicar en hibernación que se debe leer una copia nueva en lugar de la almacenada en la memoria caché de la sesión)
  3. Si es necesario, verifique el valor actual del campo de destino si cumple con sus invariantes
  4. Realizar el cambio/actualización en el campo (por ejemplo, incrementar el valor de un campo)
  5. Guarde la entidad (y asegúrese de vaciar el valor en la base de datos si no quiere esperar a que se vacíe automáticamente)
  6. Confirmar la transacción (hecho automáticamente cuando se usa @Transactional )

La diferencia esencial de esta secuencia en comparación con el método publicado es que la actualización del valor de la propiedad se realiza mientras su transacción mantiene un bloqueo en la fila de entidad/base de datos de destino , lo que evita que otras transacciones lo lean mientras su actualización está en curso.

Espero que esto ayude .

ACTUALIZACIÓN: Creo que algo así como el siguiente fragmento de código debería funcionar como se esperaba:

 @Transactional @Override public void incrementNoteCounterForGroupCanvas(int canvasId) { final Session session = this.sessionFactory.getCurrentSession(); final GroupCanvas groupCanvas = session.get(GroupCanvas.class, canvasId,LockMode.PESSIMISTIC_WRITE); session.refresh(groupCanvas); groupCanvas.setNoteCount(groupCanvas.getNoteCount()+1); session.saveOrUpdate(groupCanvas); session.flush(); }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda