[redisson] 분포식 자물쇠와 데이터베이스 업무
user_point(사용자 포인트):
id
point
1
2000
point_item(포인트 상품):
id
point
num
101
200
10
전통적인 controller, 서비스,dao 3층 구조로 데이터베이스 사무는 서비스 층(데이터베이스 MYSQL)에서 제어된다.
@RestController
@RequestMapping(value = {"point"})
public class UserPointController{
@Autowired
private UserPointService userPointService;
@RequestMapping("/exchange")
public boolean exchange(HttpServletRequest request, Long userId, Long itemId){
return userPointService.exchange(userId, itemId);
}
}
@Service
public class UserPointService {
@Resource
private RedissonClient redissonClient;
@Transaction
public boolean exchange(Long userId, Long itemId) throws Exception {
RLock lock = redissonClient.getLock("lock:" + itemId);
try {
boolean bool = lock.tryLock(10, 30, TimeUnit.SECONDS);
if (!bool){
throw new Exception(" , ");
}
UserPoint user = "select * from user_point where id = :userId";
PointItem item = "select * from point_item where id = :itemId";
if(user.point - item.point > 0 && item.num > 0){
//
>> update user_point set point = point - :item.point where id = :userId;
//
>> update point_item set num = num - 1 where id = :itemId;
return true;
}
return false;
} catch (Exception e) {
throw e;
} finally {
if(lock != null && lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
}
상기 코드를 관찰하여 생각하다.
lock.unlock()
은 Redisson-lock를 방출하는 것이다.UserPointService#exchange()
이 집행된 후이다.그래서 예시 코드에서 사실 lock,
이 나온다. lock, 。 mysql repetable-read
로 인해 발생한 문제는 현재 2개의 동시 요청{"userId": 1, "itemId": 101}
이 있다고 가정하면user 잉여 포인트 201이다.A 요청이 먼저 lock을 받았다고 가정하면 B 요청이 자물쇠를 가져올 때까지 기다립니다.A가 요청한 데이터 정보는userpoint#point=201, 이 때 교환 실행 공제를 허용하고true로 돌아갑니다.true로 돌아가기 전에 lock을 풀고 업무를 제출합니다.lock을 풀면 B 요청은 바로 자물쇠를 얻을 수 있습니다.user를 조회하면 남은 포인트를 얻을 수 있습니다:201(정확한 것은 남은 포인트:1). A 요청의 업무가 제출되지 않아서 완료될 수 있습니다!
해결 방안: 잠시lock을 controller층에 덮어쓰고 사무 제출이 성공한 후에야 자물쇠를 풀 수 있습니다!
(그림은 손이 아프고, 시차도는 인연이 있으면 다시 만나자)
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.