sql >> Database >  >> RDS >> Oracle

Hoe @lock time-out specificeren in lentegegevens jpa-query?

Voor Spring Data 1.6 of hoger

@Lock wordt ondersteund op CRUD-methoden vanaf versie 1.6 van Spring Data JPA (in feite is er al een mijlpaal verkrijgbaar). Bekijk dit ticket voor meer details.

Met die versie verklaart u eenvoudig het volgende:

interface WidgetRepository extends Repository<Widget, Long> {

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

Dit zorgt ervoor dat het CRUD-implementatiegedeelte van de backing repository-proxy het geconfigureerde LockModeType toepast op de find(…) bel de EntityManager .

Aan de andere kant,

Voor de vorige versie van Spring Data 1.6

De pessimistische lentegegevens @Lock annotaties zijn alleen van toepassing (zoals u opmerkte) op query's. Er zijn geen annotaties die ik ken die van invloed kunnen zijn op een hele transactie. U kunt een findByOnePessimistic . maken methode die findByOne . aanroept met een pessimistisch slotje of je kunt findByOne . veranderen om altijd een pessimistisch slot te krijgen.

Als u uw eigen oplossing wilde implementeren, zou u dat waarschijnlijk kunnen. Onder de motorkap de @Lock annotatie wordt verwerkt door LockModePopulatingMethodIntercceptor die het volgende doet:

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

Je zou een statische vergrendelingsmanager kunnen maken met een ThreadLocal<LockMode> member-variabele en vervolgens een aspect hebben dat om elke methode in elke repository wordt gewikkeld die bindResource aanroept met de vergrendelingsmodus ingesteld in de ThreadLocal. Hiermee kunt u de vergrendelingsmodus per thread instellen. U kunt dan uw eigen @MethodLockMode . maken annotatie die de methode zou omwikkelen in een aspect dat de threadspecifieke vergrendelingsmodus instelt voordat de methode wordt uitgevoerd en deze wist nadat de methode is uitgevoerd.

Bronlink:

  1. Hoe LockModeType.PESSIMISTIC_WRITE inschakelen bij het opzoeken van entiteiten met Spring Data JPA?
  2. Aangepast toevoegen methode om gegevens JPA te ontspringen
  3. Spring Data Pessimistic Lock-time-out met Postgres
  4. JPA-query-API

Diverse voorbeelden van pessimistische vergrendelingstime-out

Een pessimistisch slot instellen

Een entiteitsobject kan expliciet worden vergrendeld met de lock-methode:

em.lock(employee, LockModeType.PESSIMISTIC_WRITE);

Het eerste argument is een entiteitsobject. Het tweede argument is de gevraagde vergrendelingsmodus.

Een TransactionRequiredException wordt gegenereerd als er geen actieve transactie is wanneer vergrendeling wordt aangeroepen, omdat expliciete vergrendeling een actieve transactie vereist.

Een LockTimeoutException wordt gegooid als het gevraagde pessimistische slot niet kan worden verleend:

  • Een PESSIMISTIC_READ lock-verzoek mislukt als een andere gebruiker (die wordt vertegenwoordigd door een andere instantie van EntityManager) momenteel een PESSIMISTIC_WRITE heeft lock op dat database-object.
  • Een PESSIMISTIC_WRITE vergrendelingsverzoek mislukt als een andere gebruiker momenteel een PESSIMISTIC_WRITE . heeft slot of een PESSIMISTIC_READ vergrendel dat database-object.

Query-hint (bereik) instellen

Query-hints kunnen worden ingesteld in de volgende bereiken (van globaal tot lokaal):

Voor de gehele persistentie-eenheid - met behulp van een persistence.xml eigendom:

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

Voor een EntityManagerFactory - met behulp van de createEntityManagerFacotory methode:

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

Voor een EntityManager - met behulp van de createEntityManager methode:

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

of met behulp van de setProperty-methode:

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

Voor een named query definitie - met behulp van de hints element:

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

Voor een specifieke query-uitvoering - met behulp van de setHint methode (vóór uitvoering van de query):

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

Bronlink:

  1. Vergrendelen in JPA
  2. Pessimistische vergrendelingstime-out


  1. Wat is een goede manier om gegevenstoegang in te kapselen met PHP/MySQL?

  2. Niet-gevangen fout:aanroep van een lidfunctie prepare() bij null-fout

  3. SQL Server - Geneste transacties in een opgeslagen procedure

  4. Hoe PHP te dwingen nieuwe regels te lezen en terug te keren als