[SPRING] Spring, JPA, Hibernate - 동시성 문제없이 카운터를 증가시키는 방법
SPRINGSpring, JPA, Hibernate - 동시성 문제없이 카운터를 증가시키는 방법
나는 Spring과 JPA / Hibernate를 가지고 놀고 있는데 테이블의 카운터를 증가시키는 올바른 방법으로 혼란 스럽다.
내 REST API는 사용자 작업에 따라 데이터베이스에서 일부 값을 증가 및 감소시켜야합니다 (예 : 태그를 좋아하거나 싫어하면 태그가 증가하거나 감소합니다)
tagRepository는 JpaRepository (스프링 데이터) 이 같은 트랜잭션을 구성했습니다.
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"/>
@Controller
public class TestController {
@Autowired
TagService tagService
public void increaseTag() {
tagService.increaseTagcount();
}
public void decreaseTag() {
tagService.decreaseTagcount();
}
}
@Transactional
@Service
public class TagServiceImpl implements TagService {
public void decreaseTagcount() {
Tag tag = tagRepository.findOne(tagId);
decrement(tag)
}
public void increaseTagcount() {
Tag tag = tagRepository.findOne(tagId);
increment(tag)
}
private void increment(Tag tag) {
tag.setCount(tag.getCount() + 1);
Thread.sleep(20000);
tagRepository.save(tag);
}
private void decrement(Tag tag) {
tag.setCount(tag.getCount() - 1);
tagRepository.save(tag);
}
}
보시다시피 동시성 시나리오를 테스트 할 수 있으려면 .save () 전에 증분에 20 초의 수면을 취하십시오.
초기 태그 카운터 = 10;
데이터베이스를 확인할 때 태그의 값은 이제 11과 같습니다. 현실에서 (적어도 달성하고자하는 것) 10 일 때
이 행동이 정상입니까? 또는 @ Transactional 주석이 작동하지 않습니다?
해결법
-
==============================
1.가장 간단한 해결책은 동시성을 데이터베이스에 위임하고 현재 수정 된 행에 대한 데이터베이스 격리 수준 잠금에만 의존하는 것입니다.
가장 간단한 해결책은 동시성을 데이터베이스에 위임하고 현재 수정 된 행에 대한 데이터베이스 격리 수준 잠금에만 의존하는 것입니다.
증분은 다음과 같이 간단합니다.
UPDATE Tag t set t.count = t.count + 1 WHERE t.id = :id;
감소 쿼리는 다음과 같습니다.
UPDATE Tag t set t.count = t.count - 1 WHERE t.id = :id;
UPDATE 쿼리는 수정 된 행을 잠 그어 현재 트랜잭션이 커밋되기 전에 다른 트랜잭션이 동일한 행을 수정하지 못하게합니다 (READ_UNCOMMITTED를 사용하지 않는 한).
-
==============================
2.예를 들어 낙관적 잠금을 사용하십시오. 이것은 귀하의 문제를 해결하는 가장 쉬운 해결책입니다. 자세한 내용은 -> https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch05.html을 참조하십시오.
예를 들어 낙관적 잠금을 사용하십시오. 이것은 귀하의 문제를 해결하는 가장 쉬운 해결책입니다. 자세한 내용은 -> https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch05.html을 참조하십시오.
-
==============================
3.추가 할 수있는 또 다른 궁극적 인 솔루션 :
추가 할 수있는 또 다른 궁극적 인 솔루션 :
더:
from https://stackoverflow.com/questions/30143594/spring-jpa-and-hibernate-how-to-increment-a-counter-without-concurrency-issu by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 단순히 pom.xml에 slf4j를 추가하면 log4j가 어떻게 래핑됩니까? (0) | 2019.03.03 |
---|---|
[SPRING] Spring + Springfox + 헤더 매개 변수 (0) | 2019.03.03 |
[SPRING] Spring의 계층 구조를 사용하고 객체 지향 구조를 따르는 법? (0) | 2019.03.03 |
[SPRING] 자바 주석을 사용하여 로거 의존성 삽입 (0) | 2019.03.03 |
[SPRING] GWT 애플리케이션을위한 REST 백엔드를 빌드해야합니까? (0) | 2019.03.03 |