使用Lua脚本来实现,因为Redis是单线程的,又是C语言编写的,可以使用Lua调用Redis的命令,Lua会具有排他性,所以能够保证安全。
使用Lua脚本来实现,因为Redis是单线程的,又是C语言编写的,可以使用Lua调用Redis的命令,Lua会具有排他性,所以能够保证安全。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
package com.redis.secondskill;
import java.util.HashSet;
import java.util.Set;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class SS2 {
static String luaScript = "local userid=KEYS[1];\r\n" +
"local prodid=KEYS[2];\r\n" +
"local qtkey='sec:'..prodid..\":count\";\r\n" +
"local usersKey='sec:'..prodid..\":user\";\r\n" +
"local userExists=redis.call(\"sismember\",usersKey,userid);\r\n" +
"if tonumber(userExists)==1 then \r\n" +
" return 2;\r\n" +
"end\r\n" +
"local num = redis.call(\"get\" ,qtkey);\r\n" +
"if tonumber(num)<=0 then \r\n" +
" return 0;\r\n" +
"else \r\n" +
" redis.call(\"decr\",qtkey);\r\n" +
" redis.call(\"sadd\",usersKey,userid);\r\n" +
"end\r\n" +
"return 1" ;
public static boolean doSecKill(String uid,String prodid) {
JedisPool jedisPool = JedisPollTool.getInstance();
Jedis jedis = jedisPool.getResource();
String sha1 = jedis.scriptLoad(luaScript);
Object result= jedis.evalsha(sha1, 2 , uid,prodid);
String reString=String.valueOf(result);
if ( "0" .equals( reString ) ) {
System.err.println( "已抢空!!" );
} else if ( "1" .equals( reString ) ) {
System.out.println(uid + "抢购成功!!!!" );
} else if ( "2" .equals( reString ) ) {
System.err.println( "该用户已抢过!!" );
} else {
System.err.println( "抢购异常!!" );
}
JedisPollTool.distroy(jedisPool, jedis);
return true ;
}
}
|
使用Lua脚本来实现,因为Redis是单线程的,又是C语言编写的,可以使用Lua调用Redis的命令,Lua会具有排他性,所以能够保证安全。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
package com.redis.secondskill;
import java.util.HashSet;
import java.util.Set;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class SS2 {
static String luaScript = "local userid=KEYS[1];\r\n" +
"local prodid=KEYS[2];\r\n" +
"local qtkey='sec:'..prodid..\":count\";\r\n" +
"local usersKey='sec:'..prodid..\":user\";\r\n" +
"local userExists=redis.call(\"sismember\",usersKey,userid);\r\n" +
"if tonumber(userExists)==1 then \r\n" +
" return 2;\r\n" +
"end\r\n" +
"local num = redis.call(\"get\" ,qtkey);\r\n" +
"if tonumber(num)<=0 then \r\n" +
" return 0;\r\n" +
"else \r\n" +
" redis.call(\"decr\",qtkey);\r\n" +
" redis.call(\"sadd\",usersKey,userid);\r\n" +
"end\r\n" +
"return 1" ;
public static boolean doSecKill(String uid,String prodid) {
JedisPool jedisPool = JedisPollTool.getInstance();
Jedis jedis = jedisPool.getResource();
String sha1 = jedis.scriptLoad(luaScript);
Object result= jedis.evalsha(sha1, 2 , uid,prodid);
String reString=String.valueOf(result);
if ( "0" .equals( reString ) ) {
System.err.println( "已抢空!!" );
} else if ( "1" .equals( reString ) ) {
System.out.println(uid + "抢购成功!!!!" );
} else if ( "2" .equals( reString ) ) {
System.err.println( "该用户已抢过!!" );
} else {
System.err.println( "抢购异常!!" );
}
JedisPollTool.distroy(jedisPool, jedis);
return true ;
}
}
|