web-dev-qa-db-fra.com

Sélectionner pour le saut de mise à jour verrouillé du niveau JPA

Dans mon application - Oracle avec JPA (EclipseLink), j'utilise l'expression suivante pour verrouiller le sous-ensemble des enregistrements dans certaines tables:

select * from MY_TABLE where MY_CONDITIONS for update skip locked

Je l'exécute tout au long de la requête native, mais je dois écrire cette requête pour toutes les entités requises. 

Existe-t-il un moyen d'éviter les enregistrements verrouillés à l'aide de JPA pur? Puis-je mettre en œuvre ma propre politique de verrouillage?

Cela ne me dérange pas de changer de fournisseur JPA, mais je souhaite utiliser l'API JPA.

13
Dominik Kunicki

Hibernate fournit le mode de verrouillage UPGRADE_SKIPLOCKED.

Avec JPA et Hibernate, pour produire un "SKIP_LOCKED" conformément à Hibernate LockMode documentation, vous devez combiner le PESSIMISTIC_WRITE JPA LockModeType :

entityManager.find(Department.class, 1, LockModeType.PESSIMISTIC_WRITE);

et le paramètre Délai de verrouillage, comme par exemple dans persistence.xml pour votre unité de persistance:

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

(Notez que vous pouvez également configurer ce LockMode pour une requête complexe)

SKIP LOCKED ne fait pas partie de ANSI SQL. Certains SGBDR tels que ceux-ci fournissent ceci comme une fonctionnalité spécifique:

Donc, avec JPA pur, il n'est pas possible de spécifier un "SKIP LOCKED" dans les requêtes . En effet, comme indiqué dans LockModeType , JPA 2.1 prend uniquement en charge les éléments suivants:

  • NONE
  • OPTIMISTE
  • OPTIMISTIC_FORCE_INCREMENT
  • PESSIMISTIC_FORCE_INCREMENT
  • PESSIMISTIC_READ
  • PESSIMISTIC_WRITE
  • LIS
  • ÉCRIRE

Cependant, pour activer SKIP LOCKED dans votre requête, vous pouvez utiliser ces alternatives:

  • Utiliser une fonctionnalité d'implémentation JPA spécifique, telle que Hibernate LockMode qui permet de spécifier le paramètre SKIP LOCKED via une requête JPA, grâce à la combinaison du paramètre spécifique PESSIMISTIC_WRITE LockModeType Lock Timeout décrit ci-dessus.
  • Créez une requête SQL native comme vous l'avez fait
8
Rémi Bantos

Je sais que ce message est un peu vieux, mais pour mémoire, comme indiqué dans la réponse acceptée, "javax.persistence.lock.timeout" a la valeur "-2" avec les résultats d'Hibernate dans "SKIP LOCKED". Toutefois, cela peut être fait au moment de l'exécution sans avoir à définir de paramètres globaux.

Depuis 2.0 JPA permet de transmettre des astuces long comme si

entityManager.find(MyType.class, id, LockModeType.PESSIMISTIC_WRITE, new HashMap<String, Object>() {{
        put("javax.persistence.lock.timeout", "-2");
    }});
2
Pawel Zieminski

Oracle ne fournit pas de verrou de lecture, car il n'en a pas besoin. les journaux d'annulation rendent cela inutile. Donc, SELECT ... FOR UPDATE n’est en réalité qu’un verrou WRITE pour Oracle. 

Avec JPA, vous souhaitez définir LockModeType en tant que PESSIMISTIC_WRITE. 

0
gregory