Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable LockModeType.PESSIMISTIC_WRITE when looking up entities with Spring Data JPA?

How can I achieve the equivalent of this code:

tx.begin(); Widget w = em.find(Widget.class, 1L, LockModeType.PESSIMISTIC_WRITE); w.decrementBy(4); em.flush(); tx.commit(); 

... but using Spring and Spring-Data-JPA annotations?

The basis of my existing code is:

@Service @Transactional(readOnly = true) public class WidgetServiceImpl implements WidgetService {   /** The spring-data widget repository which extends CrudRepository<Widget, Long>. */   @Autowired   private WidgetRepository repo;    @Transactional(readOnly = false)   public void updateWidgetStock(Long id, int count)   {     Widget w = this.repo.findOne(id);     w.decrementBy(4);     this.repo.save(w);   } } 

But I don't know how to specify that everything in the updateWidgetStock method should be done with a pessimistic lock set.

There is a Spring Data JPA annotation org.springframework.data.jpa.repository.Lock which allows you to set a LockModeType, but I don't know if it's valid to put it on the updateWidgetStock method. It sounds more like an annotation on the WidgetRepository, because the Javadoc says:

org.springframework.data.jpa.repository
@Target(value=METHOD)
@Retention(value=RUNTIME)
@Documented
public @interface Lock
Annotation used to specify the LockModeType to be used when executing the query. It will be evaluated when using Query on a query method or if you derive the query from the method name.

... so that doesn't seem to be helpful.

How can I make my updateWidgetStock() method execute with LockModeType.PESSIMISTIC_WRITE set?

like image 836
Greg Kopff Avatar asked Apr 23 '13 01:04

Greg Kopff


People also ask

How do you implement optimistic locking in JPA?

In order to use optimistic locking, we need to have an entity including a property with @Version annotation. While using it, each transaction that reads data holds the value of the version property. Before the transaction wants to make an update, it checks the version property again.

How do you do specific locking in Spring JPA?

To specify a lock on a custom query method of a Spring Data JPA repository, we can annotate the method with @Lock and specify the required lock mode type: @Lock(LockModeType. OPTIMISTIC_FORCE_INCREMENT) @Query("SELECT c FROM Customer c WHERE c.

How do I enable spring data in JPA?

We can configure Spring Data JPA by following these steps: Enable Spring Data JPA by annotating the PersistenceContext class with the @EnableJpaRepositories annotation. Configure the base packages that are scanned when Spring Data JPA creates implementations for our repository interfaces.

What is LockModeType Pessimistic_write?

A lock with LockModeType. PESSIMISTIC_WRITE can be used when querying data and there is a high likelihood of deadlock or update failure among concurrent updating transactions. The persistence implementation must support use of locks of type LockModeType.


1 Answers

@Lock is supported on CRUD methods as of version 1.6 of Spring Data JPA (in fact, there's already a milestone available). See this ticket for more details.

With that version you simply declare the following:

interface WidgetRepository extends Repository<Widget, Long> {    @Lock(LockModeType.PESSIMISTIC_WRITE)   Widget findOne(Long id); } 

This will cause the CRUD implementation part of the backing repository proxy to apply the configured LockModeType to the find(…) call on the EntityManager.

like image 62
Oliver Drotbohm Avatar answered Sep 28 '22 06:09

Oliver Drotbohm