PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Timeout del blocco pessimistico dei dati di primavera con Postgres

javax.persistence.lock.timeout non funziona nemmeno per me quando fornito come di seguito

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

Ma poi ho provato qualcos'altro che ha funzionato. Invece di usare @Repository e usare CrudRepository, ora sto configurando il mio ibernazione usando il gestore entità. Usato createQuery insieme al blocco e all'impostazione del timeout del blocco. E questa configurazione funziona come previsto. Ho due transazioni in esecuzione in parallelo e provo a bloccare esattamente la stessa riga in DB. La prima transazione è in grado di acquisire il blocco WRITE e mantiene il blocco per circa 10 secondi prima di rilasciare il blocco. Nel frattempo, la seconda transazione tenta di acquisire il blocco sulla stessa riga, ma poiché javax.persistence.lock.timeout è impostato su 15 secondi, attende il rilascio del blocco e quindi acquisisce il proprio blocco. Quindi rendendo il flusso serializzato.

@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);
    }
}

Assicurati che questo meccanismo di blocco sia all'interno di una transazione perché il blocco verrà rilasciato quando viene eseguito il commit o il rollback di una transazione.