说明:
用redis计数器存取用户的操作次数,最多3次,但是并发会超过3次,下面的代码对吗?
BoundValueOperations<String, String> operations = redisTemplate.boundValueOps("key1");
String key1 = operations.get();
if (StringUtils.isEmpty(key1)) {
service.do();//这里是业务逻辑操作成功之后,计数器加1
operations.increment(1);
} else {
if (Integer.parseInt(key1) < 2) {
service.do();//这里是业务逻辑操作成功之后,计数器加1
operations.increment(1);
}
}
For this kind of counting business, you should count first and then do business. If the business is completed and the counter is greater than the limit value, you will be stunned.
My plan is:
Due to data inconsistency caused by concurrency, you can consider using Redis's
INCR
command to increment by 1 and get the latest value (this is a one-time operation, so it will not cause inconsistency):If it is greater than 3, it means it has been exceeded and it is over;
is less than or equal to 3, then execute the business (you may also consider the rollback counter for business execution failure).
There are certain flaws in implementing the above functions through the Java client. In the case of high concurrency, the data may be inconsistent. It is recommended to use Lua script to encapsulate the entire logic to ensure the atomicity of the operation. The script can be cached through SCRIPT LOAD. Go to the server and execute it through sha1 check value + parameters (Key, ARG) to reduce network transmission;
Give you an example:
1. Functional requirements: If the key does not exist, set it and return false, and set the timeout and count = 1; when the timeout is reached or the specified count is reached, return false and reset the timeout and count. count=1; if the timeout is not reached & the specified count is not reached, return true and incr count
redis.lua script is as follows:
The java code is as follows: