sql >> Base de Datos >  >> RDS >> PostgreSQL

Tiempo de espera de bloqueo pesimista de Spring Data con Postgres

javax.persistence.lock.timeout tampoco funciona para mí cuando se proporciona como a continuación

@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout",value = "15000")})

Pero luego probé algo más que funcionó. En lugar de usar @Repository y CrudRepository, ahora estoy configurando mi hibernación usando el administrador de entidades. Usó createQuery junto con bloqueo y configuración de tiempo de espera de bloqueo. Y esta configuración está funcionando como se esperaba. Tengo dos transacciones ejecutándose en paralelo y tratando de bloquear exactamente la misma fila en DB. La primera transacción puede adquirir el bloqueo de ESCRITURA y mantiene el bloqueo durante unos 10 segundos antes de liberarlo. Mientras tanto, la segunda transacción intenta adquirir el bloqueo en la misma fila, pero dado que javax.persistence.lock.timeout está configurado en 15 segundos, espera a que se libere el bloqueo y luego adquiere su propio bloqueo. Por lo tanto, hacer que el flujo sea serializado.

@Component
public class Repository {

    @PersistenceContext
    private EntityManager em;

    public Optional<Cache> getById(int id){
        List<Cache> list = em.createQuery("select c from Cache c where c.id = ?1")
                            .setParameter(1, id)
                            .setHint("javax.persistence.lock.timeout", 15000)
                            .setLockMode(LockModeType.PESSIMISTIC_WRITE)
                            .getResultList();


        return Optional.ofNullable(list.get(0));
    }

    public void save(Cache cache) {
        cache = em.find(Cache.class, cache.getId());
        em.merge(cache);
    }
}

Asegúrese de que este mecanismo de bloqueo esté dentro de una transacción porque el bloqueo se liberará cuando una transacción se confirme o revierta.