[SPRING] 스프링 데이터 JPA로 엔티티를 찾을 때 LockModeType.PESSIMISTIC_WRITE를 활성화하는 방법은 무엇입니까?
SPRING스프링 데이터 JPA로 엔티티를 찾을 때 LockModeType.PESSIMISTIC_WRITE를 활성화하는 방법은 무엇입니까?
이 코드와 동등한 효과를 얻으려면 어떻게해야합니까?
tx.begin();
Widget w = em.find(Widget.class, 1L, LockModeType.PESSIMISTIC_WRITE);
w.decrementBy(4);
em.flush();
tx.commit();
... Spring과 Spring-Data-JPA 주석을 사용하고 있습니까?
내 기존 코드의 기초는 다음과 같습니다.
@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);
}
}
그러나 updateWidgetStock 메소드의 모든 것이 비관적 인 잠금 세트로 수행되도록 지정하는 방법을 모르겠습니다.
LockModeType을 설정할 수있는 Spring Data JPA 어노테이션 인 org.springframework.data.jpa.repository.Lock이 있지만 updateWidgetStock 메소드에 넣을 수 있는지는 알 수 없습니다. Javadoc이 말하기를 WidgetRepository의 주석과 비슷하게 들립니다.
... 그래서 도움이되지 않는 것 같습니다.
lockModeType.PESSIMISTIC_WRITE가 설정된 상태에서 updateWidgetStock () 메서드를 실행하려면 어떻게해야합니까?
해결법
-
==============================
1.@Lock은 Spring Data JPA의 1.6 버전에서 CRUD 메소드에서 지원됩니다 (실제로 이미 마일스톤이 있습니다). 자세한 내용은이 티켓을 참조하십시오.
@Lock은 Spring Data JPA의 1.6 버전에서 CRUD 메소드에서 지원됩니다 (실제로 이미 마일스톤이 있습니다). 자세한 내용은이 티켓을 참조하십시오.
이 버전을 사용하면 다음과 같이 간단하게 선언 할 수 있습니다.
interface WidgetRepository extends Repository<Widget, Long> { @Lock(LockModeType.PESSIMISTIC_WRITE) Widget findOne(Long id); }
이것은 CRUD 구현 부분에서 Backing 저장소 프록시가 EntityManager의 find (...) 호출에 구성된 LockModeType을 적용하게합니다.
-
==============================
2.표준 findOne () 메소드를 오버라이드하고 싶지 않은 경우, select ...를 사용하여 다음과 같이 update 메소드를 사용하여 사용자 정의 메소드에서 잠금을 획득 할 수 있습니다.
표준 findOne () 메소드를 오버라이드하고 싶지 않은 경우, select ...를 사용하여 다음과 같이 update 메소드를 사용하여 사용자 정의 메소드에서 잠금을 획득 할 수 있습니다.
/** * Repository for Wallet. */ public interface WalletRepository extends CrudRepository<Wallet, Long>, JpaSpecificationExecutor<Wallet> { @Lock(LockModeType.PESSIMISTIC_WRITE) @Query("select w from Wallet w where w.id = :id") Wallet findOneForUpdate(@Param("id") Long id); }
그러나 PostgreSQL을 사용하는 경우 교착 상태를 방지하기 위해 잠금 시간 제한을 설정하려는 경우 상황이 다소 복잡해질 수 있습니다. PostgreSQL은 JPA 프로퍼티 또는 @QueryHint 주석으로 설정된 표준 프로퍼티 javax.persistence.lock.timeout을 무시합니다.
내가 작동하도록 할 수있는 유일한 방법은 사용자 저장소를 생성하고 엔티티를 잠그기 전에 수동으로 시간 초과를 설정하는 것이 었습니다. 그것은 좋지는 않지만 적어도 작동합니다.
public class WalletRepositoryImpl implements WalletRepositoryCustom { @PersistenceContext private EntityManager em; @Override public Wallet findOneForUpdate(Long id) { // explicitly set lock timeout (necessary in PostgreSQL) em.createNativeQuery("set local lock_timeout to '2s';").executeUpdate(); Wallet wallet = em.find(Wallet.class, id); if (wallet != null) { em.lock(wallet, LockModeType.PESSIMISTIC_WRITE); } return wallet; }
}
-
==============================
3.이 답변을 무시하고 올리버 (Oliver)의 대답을 참조하는 것보다 스프링 데이터 1.6 이상을 사용할 수 있다면.
이 답변을 무시하고 올리버 (Oliver)의 대답을 참조하는 것보다 스프링 데이터 1.6 이상을 사용할 수 있다면.
스프링 데이터 비관적 인 @Lock 주석은 (지적한대로) 쿼리에만 적용됩니다. 내가 아는 주석은 전체 트랜잭션에 영향을 줄 수 있습니다. 비관적 인 잠금으로 findByOne을 호출하는 findByOnePessimistic 메소드를 만들거나 항상 비관적 인 잠금을 얻기 위해 findByOne을 변경할 수 있습니다.
자신 만의 솔루션을 구현하고 싶다면 아마도 가능할 것입니다. 후드에서 @Lock 주석은 다음을 수행하는 LockModePopulatingMethodIntercceptor에 의해 처리됩니다.
TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);
ThreadLocal
멤버 변수가있는 정적 잠금 관리자를 만든 다음 ThreadLocal에 설정된 잠금 모드로 bindResource를 호출 한 모든 저장소의 모든 메서드를 래핑하는 애스펙트를 가질 수 있습니다. 이렇게하면 스레드 단위로 잠금 모드를 설정할 수 있습니다. 그런 다음 메서드를 실행하기 전에 스레드 별 잠금 모드를 설정하고 메서드를 실행 한 후이를 지우는 aspect에서 메서드를 래핑하는 @MethodLockMode 주석을 직접 만들 수 있습니다.
from https://stackoverflow.com/questions/16159396/how-to-enable-lockmodetype-pessimistic-write-when-looking-up-entities-with-sprin by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] AOP 사용의 성능 영향 (0) | 2018.12.31 |
---|---|
[SPRING] StackOverflowError로 인해 웹 응용 프로그램 [/ app]에 대한 특수 효과 검사를 완료 할 수 없습니다. (0) | 2018.12.31 |
[SPRING] 어느 spring view resolver가 angularjs와 잘 맞습니까? (0) | 2018.12.31 |
[SPRING] Spring 3 MVC AOP 인터셉터를 가진 @Controller? (0) | 2018.12.31 |
[SPRING] 선택적으로 Spring 데이터 Rest 응답의 연관을 확장합니다. (0) | 2018.12.31 |