运行一万笔,抢10笔商品,运行完毕,抢购控制成功,但是运行失败和总次数不够一万,这个问题还在排查,失败的条数每次运行不一致,
参考 https://www.jianshu.com/p/43b786079a1e
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisWatchTest {
private static final Logger logger = LoggerFactory.getLogger(RedisTransactionTest.class);
@Autowired
RedisUtil redis;
@Autowired
private RedisTemplate<String, String> redisTemplate;
private String watchKey = "watchKey";
@Test
public void test() {
Jedis jedis = new Jedis("127.0.0.1",6379);
jedis.auth("123456"); //设置密码
redisTemplate.watch(watchKey);
ExecutorService executor = Executors.newFixedThreadPool(20);
jedis.set(watchKey, "0"); //重置watchkey 为0
jedis.del("setSucc","setFail"); //清空抢成功的和失败的
jedis.close();
for(int i=0;i<10000;i++) {
executor.execute(new RedisWatchRunner());
}
executor.shutdown();
}
}
public class RedisWatchRunner implements Runnable{
private static final Logger logger = LoggerFactory.getLogger(RedisTransactionTest.class);
// @Autowired
// RedisUtil redis;
@Autowired
private RedisTemplate<String, String> redisTemplate;
private String watchKey = "watchKey";
@Override
public void run() {
System.out.println("进入抢购环节");
// TODO Auto-generated method stub
try {
Jedis jedis = new Jedis("127.0.0.1",6379);
jedis.auth("123456"); //设置密码
jedis.watch(watchKey);
String val = (String) jedis.get(watchKey);
System.out.println("当前value:" + val);
int valInt = Integer.valueOf(val);
String userInfo = UUID.randomUUID().toString();
/**
* 一万个用户一共抢购10个产品
*/
if(valInt < 10) {
Transaction tx = jedis.multi(); //开启事务
tx.incr(watchKey);
List<Object> list = tx.exec(); //提交事务,如果此时 watchKey 值变动,返回null
if(list != null) {
System.out.println("用户" + userInfo + "抢购成功,当前抢购成功人数为:" + (valInt + 1));
/**抢购成功业务逻辑 */
jedis.sadd("setSucc", userInfo);
}else {
System.out.println("用户进入" + userInfo + "抢购失败");
jedis.sadd("setFail", userInfo);
}
}else {
System.out.println("用户未进入" + userInfo + "抢购失败");
jedis.sadd("setFail", userInfo);
return;
}
}catch(Exception e) {
e.printStackTrace();
}finally {
}
}
}
总量改成1千和2千运行的总数是正常的,