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:
- Hoe LockModeType.PESSIMISTIC_WRITE inschakelen bij het opzoeken van entiteiten met Spring Data JPA?
- Aangepast toevoegen methode om gegevens JPA te ontspringen
- Spring Data Pessimistic Lock-time-out met Postgres
- 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_READlock-verzoek mislukt als een andere gebruiker (die wordt vertegenwoordigd door een andere instantie van EntityManager) momenteel eenPESSIMISTIC_WRITEheeft lock op dat database-object. - Een
PESSIMISTIC_WRITEvergrendelingsverzoek mislukt als een andere gebruiker momenteel eenPESSIMISTIC_WRITE. heeft slot of eenPESSIMISTIC_READvergrendel 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);