entityManager.lock(myObject, LockModeType.OPTIMISTIC);  import lombok.Getter; import lombok.Setter; import javax.persistence.*; @EntityListeners(OperationListenerForMyEntity.class) @Entity public class MyEntity{ @Version private long version; @Id @GeneratedValue @Getter @Setter private Integer id; @Getter @Setter private String value; @Override public String toString() { return "MyEntity{" + "id=" + id + ", version=" + version + ", value='" + value + '\'' + '}'; } }  import javax.persistence.*; public class OperationListenerForMyEntity { @PostLoad public void postLoad(MyEntity obj) { System.out.println("Loaded operation: " + obj); } @PrePersist public void prePersist(MyEntity obj) { System.out.println("Pre-Persistiting operation: " + obj); } @PostPersist public void postPersist(MyEntity obj) { System.out.println("Post-Persist operation: " + obj); } @PreRemove public void preRemove(MyEntity obj) { System.out.println("Pre-Removing operation: " + obj); } @PostRemove public void postRemove(MyEntity obj) { System.out.println("Post-Remove operation: " + obj); } @PreUpdate public void preUpdate(MyEntity obj) { System.out.println("Pre-Updating operation: " + obj); } @PostUpdate public void postUpdate(MyEntity obj) { System.out.println("Post-Update operation: " + obj); } }  import javax.persistence.*; import java.util.concurrent.*; //        ,   . public class Main { //  , ..  EntityManagerFactory  ,     . private static EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("ru.easyjava.data.jpa.hibernate"); public static void main(String[] args) { //  10 (  ,       ). ExecutorService es = Executors.newFixedThreadPool(10); try { //  persistFill()   - . persistFill(); for(int i=0; i<10; i++){ int finalI = i; es.execute(() -> { //      updateEntity(finalI) ,  java       .    java -  ,      id,       , id    ,       (  ,      persistFill(),  id       500). updateEntity(finalI); }); } es.shutdown(); try { es.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } } finally { entityManagerFactory.close(); } } //         . private static void updateEntity(int index) { //  EntityManager  ,     ,    . EntityManager em = entityManagerFactory.createEntityManager(); MyEntity myEntity = null; try { em.getTransaction().begin(); //        1. myEntity = em.find(MyEntity.class, 1); //   sout,       "" . System.out.println("load = "+index); //       (  LockModeType.*). em.lock(myEntity, LockModeType.OPTIMISTIC); //   Value,  ,        . myEntity.setValue("WoW_" + index); em.getTransaction().commit(); em.close(); System.out.println("--Greeter updated : " + myEntity +" __--__ "+ index); }catch(RollbackException ex){ System.out.println(", =" + myEntity); } } public static void persistFill() { MyEntity myEntity = new MyEntity(); myEntity.setValue("JPA"); EntityManager em = entityManagerFactory.createEntityManager(); em.getTransaction().begin(); em.persist(myEntity); em.getTransaction().commit(); em.close(); } }  Pre-Persistiting operation: MyEntity{id=null, version=0, value='JPA'} Post-Persist operation: MyEntity{id=531, version=0, value='JPA'}  .  id   find   .  Loaded operation: MyEntity{id=531, version=0, value='JPA'} load = 3 Loaded operation: MyEntity{id=531, version=0, value='JPA'} load = 2 Pre-Updating operation: MyEntity{id=531, version=0, value='WoW_2'} Pre-Updating operation: MyEntity{id=531, version=0, value='WoW_3'} Loaded operation: MyEntity{id=531, version=0, value='JPA'} load = 9 Pre-Updating operation: MyEntity{id=531, version=0, value='WoW_9'} Loaded operation: MyEntity{id=531, version=0, value='JPA'} load = 1 Pre-Updating operation: MyEntity{id=531, version=0, value='WoW_1'} Post-Update operation: MyEntity{id=531, version=1, value='WoW_1'} --Greeter updated : MyEntity{id=531, version=1, value='WoW_1'} __--__ 1 , =MyEntity{id=531, version=0, value='WoW_2'} , =MyEntity{id=531, version=0, value='WoW_3'} Loaded operation: MyEntity{id=531, version=1, value='WoW_1'} load = 4 Pre-Updating operation: MyEntity{id=531, version=1, value='WoW_4'} Post-Update operation: MyEntity{id=531, version=2, value='WoW_4'} --Greeter updated : MyEntity{id=531, version=2, value='WoW_4'} __--__ 4 , =MyEntity{id=531, version=0, value='WoW_9'} Loaded operation: MyEntity{id=531, version=2, value='WoW_4'} load = 0 Pre-Updating operation: MyEntity{id=531, version=2, value='WoW_0'} Post-Update operation: MyEntity{id=531, version=3, value='WoW_0'} --Greeter updated : MyEntity{id=531, version=3, value='WoW_0'} __--__ 0 Loaded operation: MyEntity{id=531, version=3, value='WoW_0'} load = 6 Pre-Updating operation: MyEntity{id=531, version=3, value='WoW_6'} Post-Update operation: MyEntity{id=531, version=4, value='WoW_6'} Loaded operation: MyEntity{id=531, version=4, value='WoW_6'} load = 5 Pre-Updating operation: MyEntity{id=531, version=4, value='WoW_5'} Post-Update operation: MyEntity{id=531, version=5, value='WoW_5'} --Greeter updated : MyEntity{id=531, version=4, value='WoW_6'} __--__ 6 --Greeter updated : MyEntity{id=531, version=5, value='WoW_5'} __--__ 5 Loaded operation: MyEntity{id=531, version=5, value='WoW_5'} load = 7 Pre-Updating operation: MyEntity{id=531, version=5, value='WoW_7'} Post-Update operation: MyEntity{id=531, version=6, value='WoW_7'} Loaded operation: MyEntity{id=531, version=5, value='WoW_5'} load = 8 Pre-Updating operation: MyEntity{id=531, version=5, value='WoW_8'} --Greeter updated : MyEntity{id=531, version=6, value='WoW_7'} __--__ 7 , =MyEntity{id=531, version=5, value='WoW_8'}  load = 0 Pre-Updating operation: MyEntity{id=549, version=5, value='WoW_0'} Post-Update operation: MyEntity{id=549, version=6, value='WoW_0'} Loaded operation: MyEntity{id=549, version=6, value='WoW_0'} load = 8 Pre-Updating operation: MyEntity{id=549, version=6, value='WoW_8'} Loaded operation: MyEntity{id=549, version=6, value='WoW_0'} load = 4 Pre-Updating operation: MyEntity{id=549, version=6, value='WoW_4'} ... ERROR: :   :  22760    ExclusiveLock  " (0,66)  287733   271341";   20876.  20876    ShareLock  " 8812";   22760. Source: https://habr.com/ru/post/434836/
All Articles