inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

실전! 스프링 데이터 JPA

소개

순수 Repository에도 락을 걸 수 있을까요?

246

코린코린

작성한 질문수 53

0

안녕하세요.
항상 좋은 강의와 답변 주셔서 감사합니다.
 
강의를 다 듣지 못해서 ㅠㅠ... 죄송하지만..
여기에 글을 적게 되었습니다.
 
제가 JPA의 DB쪽 동시성 병렬성 문제를 고민하던 중... @Lcok이라는 기능을 통해 DB쪽 문제까지 해결할 수 있다는 것을 알게 되어서... @LOCK을 순수 Repository나 Service에 걸려고 했었습니다.
 
그런데 하다 보니 @Lock이 Spring Data JPA 패키지에 있더라구요. 그래서 구글링을 해보니 많은 분들께서 JPA Repository 구현체에다가 @Lock을 적용하시는 것 같았습니다.
 
혹시 Spring Data Jpa Repository의 구현체가 아닌 순수 JPA에서도 @Lock 어노테이션을 정상적으로 사용할 수 있을까요?
제가 비관적 락을 걸고, Version으로 관리하는 코드를 작성해서 돌려봤는데... 비관적 락이 아니라, default인 낙관적 락으로 계속 돌아가는 것 같습니다... 다른 분들이 자겅한 코드를 확인해보니, JPA Repository 구현체에서는 정상적으로 @Lock이 먹히는 거 같습니다...
 
혹시 바쁘시겠지만... 알려주시면 너무 감사드리겠습니다...!
 
 
엔티티 코드
@Entity
@Data
public class MyEntity {

@Id
@GeneratedValue
private Long id;

private Long num;

@Version
private Long version;
}
 
 
리포지토리 코드
@Repository
@RequiredArgsConstructor
public class MyRepository {

private final EntityManager em;

@Transactional
@Lock(value = LockModeType.PESSIMISTIC_FORCE_INCREMENT)
public MyEntity save(MyEntity entity) {
em.persist(entity);
return entity;
}

public MyEntity findById(Long entityId) {
return em.find(MyEntity.class, entityId);
}
}

 
서비스 코드
@Service
@RequiredArgsConstructor
public class MyService {

private final MyRepository myRepository;


@Transactional
public MyEntity save(MyEntity entity) {
entity.setNum(entity.getNum() + 1);
myRepository.save(entity);
return entity;
}

@Transactional
public MyEntity saveEntity(Long entityId) {
MyEntity entity = myRepository.findById(entityId);
entity.setNum(entity.getNum() + 1);
myRepository.save(entity);
return entity;
}

}
 
테스트 코드 --> 돌리는 도중 낙관적 락에 의한 예외 코드 발생하며 종료
@SpringBootTest
public class MyEntityTest {


private static final ExecutorService service =
Executors.newFixedThreadPool(3);

@Autowired
private MyRepository myRepository;

@Autowired
private MyService myService;

private long accountId;
private Long entityId;

@BeforeEach
public void setUp() {

MyEntity myEntity = new MyEntity();
myEntity.setNum(10L);
myService.save(myEntity);
entityId = myEntity.getId();

}

@Test
public void raceCond() throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
service.execute(() -> {
myService.saveEntity(entityId);
latch.countDown();
});
}
latch.await();


System.out.println("myRepository.findById(entityId) = " + myRepository.findById(entityId));
}
 
 
 
 
 
 
 
 
항상 좋은 강의와 답변 감사드립니다.
 

spring-boot java spring JPA

답변 1

0

김영한

안녕하세요. 안상혁님^^

JPA 책 16.1 트랜잭션과 락 부분을 참고해주세요.

감사합니다

changeTeam 메서드 질문

0

34

1

existsByUserIdAndProjectId vs existsByUserAndProject 중 어떤 방식이 적절할까요?

0

87

1

existsByUserIdAndProjectId vs existsByUserAndProject 중 어떤 방식이 적절할까요?

0

128

3

MemberRepository 구현체

0

71

1

pdf 표현 질문드립니다.

0

77

1

로그가 남지 않는 문제.

0

98

1

테스트 라이브러리가 강의는 junit4가 맞나요??

0

78

2

pdf 파일과 차이점이 있는 것같은데 문제 없나요?

0

75

2

@PrePersist, @PreUpdate 호출 시점 질문드립니다.

0

102

2

Sort 인터페이스는 잘 사용 안하나요?

0

59

1

스캔대상 질문드립니다.

0

48

1

하이버네이트6에서의 최적화에 이은 질문

0

92

1

save() vs saveAndFlush DB 통신 횟수

0

58

1

순수 JPA 리포지토리 코드 수정부분

0

92

2

bulk연산 후 flush하는 이유를 모르겠어요

0

163

3

bulk insert 질문입니다.

0

191

2

교만했던 것 같아요.

0

152

1

RESTful 강의는 안하시는 건지 궁금합니다.

0

154

2

동적 테이블에 대한 질문

0

89

1

영속성 전이와 연관관계

0

141

2

강의 10:25 질문

0

78

1

단건 update 질문

0

104

2

엔티티 와 도메인의 경계

0

129

1

UsernameOnlyDto 타입 type mismatch 오류

0

123

1