PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Spring Data Pessimistic Lock timeout com Postgres


javax.persistence.lock.timeout também não está funcionando para mim quando fornecido como abaixo
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout",value = "15000")})

Mas então eu tentei outra coisa que funcionou. Em vez de usar @Repository e usar CrudRepository, agora estou configurando minha hibernação usando o gerenciador de entidades. Usado createQuery junto com bloqueio e definindo o tempo limite de bloqueio. E esta configuração está funcionando como esperado. Eu tenho duas transações em paralelo e tentando bloquear exatamente a mesma linha no banco de dados. A primeira transação é capaz de adquirir o bloqueio WRITE e mantém o bloqueio por cerca de 10 segundos antes de liberar o bloqueio. Enquanto isso, a segunda transação tenta adquirir o bloqueio na mesma linha, mas como javax.persistence.lock.timeout está definido como 15 segundos, ele espera que o bloqueio seja liberado e então adquire seu próprio bloqueio. Portanto, tornando o fluxo 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);
    }
}

Certifique-se de que esse mecanismo de bloqueio esteja dentro de uma transação porque o bloqueio será liberado quando uma transação for confirmada ou revertida.