programing

잠금 모드 유형을 활성화하는 방법.Spring Data JPA를 사용하여 엔티티를 조회할 때의 SEPMISTIC_WRITE?

codeshow 2023. 8. 26. 00:08
반응형

잠금 모드 유형을 활성화하는 방법.Spring Data JPA를 사용하여 엔티티를 조회할 때의 SEPMISTIC_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메서드는 비관적 잠금 세트로 수행해야 합니다.

Spring Data JPA 주석이 있습니다.org.springframework.data.jpa.repository.Lock설정할 수 있습니다.LockModeType하지만 그것을 위에 올리는 것이 유효한지는 모르겠습니다.updateWidgetStock방법.그것은 더 많은 주석처럼 들립니다.WidgetRepository자바독이 말하기를

org.springframework.data.jpa.저장소
@대상(값=DICOM)
@유지(값=런타임)
@문서화됨
public @인터페이스 잠금
쿼리를 실행할 때 사용할 LockModeType을 지정하는 데 사용되는 주석입니다.쿼리 메서드에서 쿼리를 사용하거나 메서드 이름에서 쿼리를 파생할 때 평가됩니다.

그래서 그것은 도움이 되지 않는 것 같습니다.

어떻게 만들 수 있습니까?updateWidgetStock()메소드 실행 방법LockModeType.PESSIMISTIC_WRITE세트?

@Lock는 Spring Data JPA 버전 1.6의 CRUD 방법에서 지원됩니다(사실 이미 마일스톤을 사용할 수 있습니다).자세한 내용은 이 티켓을 참조하십시오.

해당 버전에서는 다음을 선언하기만 하면 됩니다.

interface WidgetRepository extends Repository<Widget, Long> {

  @Lock(LockModeType.PESSIMISTIC_WRITE)
  Widget findOne(Long id);
}

이로 인해 백업 저장소 프록시의 CRUD 구현 부분이 구성된 항목을 적용합니다.LockModeType에게find(…)방문.EntityManager.

표준을 재정의하지 않으려면findOne()메소드, 당신은 당신의 사용자 정의 메소드에서 잠금을 획득할 수 있습니다.select ... for 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);
}

그러나 Postgre를 사용하는 경우SQL, 교착 상태를 방지하기 위해 잠금 시간 초과를 설정하려면 상황이 조금 복잡해질 수 있습니다.포스트그레SQL이 표준 속성을 무시함javax.persistence.lock.timeoutJPA 속성 또는 에 설정@QueryHint주석

사용자 지정 저장소를 만들고 엔티티를 잠그기 전에 시간 초과를 수동으로 설정하는 방법밖에 없었습니다.좋지는 않지만 적어도 효과는 있습니다.

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;
}

}

Spring Data 1.6 이상을 사용할 수 있는 경우 이 답변을 무시하고 Oliver의 답변을 참조하십시오.

비관적인 봄 데이터@Lock주석은 사용자가 지적한 대로 쿼리에만 적용됩니다.전체 트랜잭션에 영향을 줄 수 있는 주석이 없습니다.다음을 생성할 수 있습니다.findByOnePessimistic 부르는 findByOne인 잠금을 할 수 .findByOne항상 비관적인 잠금을 얻습니다.

독자적인 솔루션을 구현하고 싶다면 가능할 것입니다.에 후드아에래에▁under.@Lock은 다음과 같이 됩니다.LockModePopulatingMethodIntercceptor다음 작업을 수행합니다.

TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);

할 수 있습니다. 정적 잠금 관리자를 생성할 수 .ThreadLocal<LockMode>한 후 .bindResource를 잠모 드된 상태서 ThreadLocal이렇게 하면 스레드 단위로 잠금 모드를 설정할 수 있습니다.그런 다음 자신의 데이터를 생성할 수 있습니다.@MethodLockMode메서드를 실행하기 전에 스레드별 잠금 모드를 설정하고 메서드를 실행한 후에 삭제하는 측면으로 메서드를 래핑하는 주석입니다.

언급URL : https://stackoverflow.com/questions/16159396/how-to-enable-lockmodetype-pessimistic-write-when-looking-up-entities-with-sprin

반응형