2

I'm using the Spring Boot JPA, with TransactionTemplate and pessimistic lock, I'm trying to prevent the record from being updated by other thread during the transaction. Here is the code:

    transactionService.executeTransaction(() -> {
        Map<String, Object> properties = new HashMap<>();
        properties.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED);
        System.out.println("--------------------- start find with lock, job id: " + entityId);
        Entity newEntity = (Entity) em.find(entityClass, entityId, LockModeType.PESSIMISTIC_WRITE, properties);
        System.out.println("+++++++++++++++++++++ end find with lock, job id: " + entityId);
        try{
            Thread.sleep(2000);
        }catch (InterruptedException e){

        }
        newEntity = setEntity.setEntity(newEntity);
        System.out.println(Thread.currentThread().getName() + ": use transaction to save: " + newEntity.getId());
    });

There is another thread with a while loop, and trying to update the record. Something like below:

while(true){
    Entity entity = entity.findOne(id);
    repository.save(entity);
    System.out.println("save success: " + id)
}

But I have found that the pessimistic lock not work at all, during the print between "start find with lock" and "end find with lock", and also the 2 seconds sleep, I found the entity always can be saved by the other thread. Do I have some misunderstanding with pessimistic lock?

EDIT 1: I have debug and see the sql.

em.find(entityClass, entityId, LockModeType.PESSIMISTIC_WRITE, properties);

has generated two sql, one has none join to any other table, but has "for update"

SELECT * FROM ... WHERE ID=? FOR UPDATE

And the other one is, with join but no "for update"

SLECT * FROM ... left outer join ... left outer join ... where id=? 

Hope this can help.

Man Shen
  • 401
  • 2
  • 16
  • pessimistic lock should create an SQL statement like "SELECT ... FOR UPDATE" as per the JPA spec. Perhaps you ought to debug your situation by looking at your JPA providers log for what SQL they send. –  Feb 23 '19 at 10:21
  • @BillyFrost add the sql, there is one sql with "for update" – Man Shen Feb 23 '19 at 11:00

1 Answers1

0

Yes, if you are using Hibernate as your JPA implementation, it's yet to be supported. So the lock won't extend to the joins

The javax.persistence.lock.scope is not yet supported as specified by the JPA standard.

From Hibernate Docs

Related Ticket

Enoobong
  • 1,594
  • 2
  • 15
  • 25