Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment spécifier le délai d'attente @lock dans la requête jpa de données de printemps?

Pour Spring Data 1.6 ou supérieur

@Lock est pris en charge sur les méthodes CRUD à partir de la version 1.6 de Spring Data JPA (en fait, il existe déjà un jalon disponible). Voir ce ticket pour plus de détails.

Avec cette version, vous déclarez simplement ce qui suit :

interface WidgetRepository extends Repository<Widget, Long> {

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

Cela amènera la partie implémentation CRUD du proxy du référentiel de sauvegarde à appliquer le LockModeType configuré au find(…) appeler le EntityManager .

D'autre part,

Pour la version précédente de Spring Data 1.6

Le pessimiste de Spring Data @Lock les annotations ne s'appliquent (comme vous l'avez souligné) qu'aux requêtes. Il n'y a pas d'annotations que je connaisse qui puissent affecter une transaction entière. Vous pouvez soit créer un findByOnePessimistic méthode qui appelle findByOne avec un verrou pessimiste ou vous pouvez changer findByOne pour toujours obtenir une serrure pessimiste.

Si vous vouliez implémenter votre propre solution, vous le pourriez probablement. Sous le capot le @Lock l'annotation est traitée par LockModePopulatingMethodIntercceptor qui fait ce qui suit :

TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);

Vous pourriez créer un gestionnaire de verrouillage statique qui avait un ThreadLocal<LockMode> membre variable et ensuite avoir un aspect enroulé autour de chaque méthode dans chaque référentiel qui a appelé bindResource avec le mode de verrouillage défini dans le ThreadLocal. Cela vous permettrait de définir le mode de verrouillage sur une base par thread. Vous pouvez alors créer votre propre @MethodLockMode annotation qui envelopperait la méthode dans un aspect qui définit le mode de verrouillage spécifique au thread avant d'exécuter la méthode et l'efface après l'exécution de la méthode.

Lien vers la ressource :

  1. Comment activer LockModeType.PESSIMISTIC_WRITE lors de la recherche d'entités avec Spring Data JPA ?
  2. Comment ajouter une méthode personnalisée méthode à Spring Data JPA
  3. Délai de verrouillage pessimiste des données Spring avec Postgres
  4. API de requête JPA

Divers exemples de délai d'attente de verrouillage pessimiste

Configuration d'un verrou pessimiste

Un objet entité peut être verrouillé explicitement par la méthode lock :

em.lock(employee, LockModeType.PESSIMISTIC_WRITE);

Le premier argument est un objet entité. Le deuxième argument est le mode de verrouillage demandé.

Une TransactionRequiredException est lancé s'il n'y a pas de transaction active lorsque le verrou est appelé car le verrouillage explicite nécessite une transaction active.

Une LockTimeoutException est levée si le verrou pessimiste demandé ne peut pas être accordé :

  • Un PESSIMISTIC_READ la demande de verrouillage échoue si un autre utilisateur (qui est représenté par une autre instance EntityManager) détient actuellement un PESSIMISTIC_WRITE verrouille cet objet de base de données.
  • Un PESSIMISTIC_WRITE la demande de verrouillage échoue si un autre utilisateur détient actuellement soit un PESSIMISTIC_WRITE serrure ou un PESSIMISTIC_READ verrouiller cet objet de base de données.

Définition de l'indicateur de requête (étendues)

Les indicateurs de requête peuvent être définis dans les portées suivantes (du global au local) :

Pour toute l'unité de persistance - en utilisant un persistence.xml propriété :

<properties>
   <property name="javax.persistence.query.timeout" value="3000"/>
</properties>

Pour une EntityManagerFactory - en utilisant createEntityManagerFacotory méthode :

Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 4000);
EntityManagerFactory emf =
  Persistence.createEntityManagerFactory("pu", properties);

Pour un EntityManager - en utilisant le createEntityManager méthode :

Map<String,Object> properties = new HashMap();
properties.put("javax.persistence.query.timeout", 5000);
EntityManager em = emf.createEntityManager(properties);

ou en utilisant la méthode setProperty :

em.setProperty("javax.persistence.query.timeout", 6000);

Pour une named query définition - en utilisant les hints élément :

@NamedQuery(name="Country.findAll", query="SELECT c FROM Country c",
    hints={@QueryHint(name="javax.persistence.query.timeout", value="7000")})

Pour une exécution de requête spécifique - en utilisant le setHint méthode (avant l'exécution de la requête) :

query.setHint("javax.persistence.query.timeout", 8000);

Lien vers la ressource :

  1. Verrouillage dans JPA
  2. Délai de verrouillage pessimiste