Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como especificar o tempo limite @lock na consulta jpa de dados de mola?

Para Spring Data 1.6 ou superior


@Lock é suportado em métodos CRUD a partir da versão 1.6 do Spring Data JPA (na verdade, já existe um marco acessível). Veja este ingresso para mais detalhes.

Com essa versão você simplesmente declara o seguinte:
interface WidgetRepository extends Repository<Widget, Long> {

  @Lock(LockModeType.PESSIMISTIC_WRITE)
  Widget findOne(Long id);
}

Isso fará com que a parte de implementação CRUD do proxy do repositório de apoio aplique o LockModeType configurado ao find(…) chame o EntityManager .

Por outro lado,

Para a versão anterior do Spring Data 1.6


O pessimista do Spring Data @Lock as anotações só se aplicam (como você apontou) às consultas. Não há anotações que eu conheça que possam afetar uma transação inteira. Você pode criar um findByOnePessimistic método que chama findByOne com um bloqueio pessimista ou você pode alterar findByOne obter sempre um bloqueio pessimista.

Se você quisesse implementar sua própria solução, provavelmente conseguiria. Sob o capô, o @Lock a anotação é processada por LockModePopulatingMethodIntercceptor que faz o seguinte:
TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);

Você poderia criar algum gerenciador de bloqueio estático que tivesse um ThreadLocal<LockMode> member variável e, em seguida, ter um aspecto envolvido em cada método em cada repositório que chamou bindResource com o modo de bloqueio definido no arquivo ThreadLocal. Isso permitiria que você defina o modo de bloqueio por thread. Você pode então criar seu próprio @MethodLockMode anotação que envolveria o método em um aspecto que define o modo de bloqueio específico do thread antes de executar o método e o limpa após executar o método.

Link do recurso:

  1. Como habilitar LockModeType.PESSIMISTIC_WRITE ao pesquisar entidades com Spring Data JPA?
  2. Como adicionar personalizado método para Spring Data JPA
  3. Tempo limite de bloqueio pessimista do Spring Data com Postgres
  4. API de consulta JPA

Vários exemplos de tempo limite de bloqueio pessimista

Definindo um bloqueio pessimista


Um objeto de entidade pode ser bloqueado explicitamente pelo método de bloqueio:
em.lock(employee, LockModeType.PESSIMISTIC_WRITE);

O primeiro argumento é um objeto de entidade. O segundo argumento é o modo de bloqueio solicitado.

Uma TransactionRequiredException é lançado se não houver nenhuma transação ativa quando o bloqueio for chamado porque o bloqueio explícito requer uma transação ativa.

Uma LockTimeoutException é lançado se o bloqueio pessimista solicitado não puder ser concedido:
  • Um PESSIMISTIC_READ a solicitação de bloqueio falhará se outro usuário (representado por outra instância do EntityManager) tiver umPESSIMISTIC_WRITE lock nesse objeto de banco de dados.
  • Um PESSIMISTIC_WRITE a solicitação de bloqueio falhará se outro usuário possuir um PESSIMISTIC_WRITE bloqueio ou um PESSIMISTIC_READ bloquear nesse objeto de banco de dados.

Definindo a dica de consulta (escopos)


As dicas de consulta podem ser definidas nos seguintes escopos (de global a local):

Para toda a unidade de persistência - usando um persistence.xml propriedade:
<properties>
   <property name="javax.persistence.query.timeout" value="3000"/>
</properties>

Para um EntityManagerFactory - usando o createEntityManagerFacotory método:
Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 4000);
EntityManagerFactory emf =
  Persistence.createEntityManagerFactory("pu", properties);

Para um EntityManager - usando o createEntityManager método:
Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 5000);
EntityManager em = emf.createEntityManager(properties);

ou usando o método setProperty:
em.setProperty("javax.persistence.query.timeout", 6000);

Para uma named query definição - usando as hints elemento:
@NamedQuery(name="Country.findAll", query="SELECT c FROM Country c",
    hints={@QueryHint(name="javax.persistence.query.timeout", value="7000")})

Para uma execução de consulta específica - usando o setHint método (antes da execução da consulta):
query.setHint("javax.persistence.query.timeout", 8000);

Link do recurso:

  1. Bloqueando em JPA
  2. Tempo limite de bloqueio pessimista