需求是这样的:
用户每天最多领取礼包3次,每次insert一条记录,但是在并发的情况下会超出3次,如果解决?
有个已知的方法如下,但是并发下会产生死锁
INSERT INTO t_test (gift_id, user_id, `date`) SELECT v_gift_id, v_user_id, v_date FROM dual WHERE not exists (select * from t_test where `user_id` = v_user_id and `date` = v_date GROUP BY `user_id`, `date` HAVING count(*) > 2);
@junze님 말씀처럼 주로
redis
로 마무리됩니다.예를 들어
인 경우redis
에insert
각 사용자의 횟수를 저장합니다.key
형식이user:count
먼저
count
의 값을 매번 확인하여 3보다 작으면 삽입을 수행하고insert
의 결과를 판단합니다. 삽입이 성공하면key
user:count
에 대해incr
을 실행합니다. ,incr user:count
, 쓰기 실패incr
가 실행되지 않습니다.이렇게 하면 3을 초과하는 높은 동시성을 방지할 수 있습니다.
동시에
key
의 만료 시간expire user:count 60*60*24
을 1일로 설정할 수 있습니다. 하루가 지나면 키가 삭제되고 다음날 다시 초기화됩니다.계산을 위해 문자열 유형의 redis를 사용하세요. Redis는 높은 동시성을 더 효과적으로 지원합니다
MySQL에서는 이 작업을 수행할 수 없습니다. 사용자의 선물 패키지 수를 캐시에 저장하고, 사용자 ID를 기반으로 캐시 키로 일부 상수를 추가하고, 여기에 숫자를 저장하고, 매번 캐시에서 검색할 수 있습니다. 횟수를 꺼내어 숫자보다 작은지 판단하고, 숫자보다 작으면 계속하세요. 계속하면 삽입 후 숫자가 1씩 증가하여 캐시에 저장됩니다.
논리 계층에서 수행하는 것이 좋습니다
Mysql에는 이런 메커니즘이 없는 것 같은데, 이 컨트롤도 논리적 컨트롤인 것 같아요
mysql을 사용해야 한다면 트랜잭션을 사용하여 이를 보장하세요.