From bfc459bc73d428b7309559eca4b64a500a6e5d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Tue, 11 Jun 2019 14:44:46 +0200 Subject: [PATCH] doc: how to lock with Panache How to implement a JPA lock with Panache --- .../asciidoc/hibernate-orm-panache-guide.adoc | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/docs/src/main/asciidoc/hibernate-orm-panache-guide.adoc b/docs/src/main/asciidoc/hibernate-orm-panache-guide.adoc index edf06aaf2dcff..98808b8cefc84 100644 --- a/docs/src/main/asciidoc/hibernate-orm-panache-guide.adoc +++ b/docs/src/main/asciidoc/hibernate-orm-panache-guide.adoc @@ -381,6 +381,37 @@ Make sure to wrap methods modifying your database (e.g. `entity.persist()`) with CDI bean method `@Transactional` will do that for you and make that method a transaction boundary. We recommend doing so at your application entry point boundaries like your REST endpoint controllers. +== Lock management + +Panache does not provide direct support for database locking, but you can do it by injecting the `EntityManager` in your entity (or `PanacheRepository`) and creating a specific method that will use the entity manager to lock the entity after retrieval. The entity manager can also be retrieved via `Panache.getEntityManager()`. + +The following example contains a `findByIdForUpdate` method that finds the entity by primary key then locks it. The lock will generate a `SELECT ... FOR UPDATE` query (the same principle can be used for other kinds of `find*` methods): + +[source,java] +-- +@Entity +public class Person extends PanacheEntity { + public String name; + public LocalDate birth; + public Status status; + + // inject the EntityManager inside the entity + @Inject + EntityManager entityManager; + + public static Person findByIfForUpdate(Long id){ + Person person = findById(id); + //lock with the PESSIMISTIC_WRITE mode type : this will generate a SELECT ... FOR UPDATE query + entityManager.lock(person, LockModeType.PESSIMISTIC_WRITE); + return person; + } +} +-- + +This will generate two select queries: one to retrieve the entity and the second to lock it. Be careful that locks are released when the transaction ends, so the method that invokes the lock query must be annotated with the `@Transactional` annotation. + +We are currently evaluating adding support for lock management inside Panache. If you are interested, please visit our github issue link:https://github.com/quarkusio/quarkus/issues/2744[#2744] and contribute to the discussion. + == Custom IDs IDs are often a touchy subject, and not everyone's up for letting them handled by the framework, once again we