Redis的事务中启用的是乐观锁,只负责监测key没有被改动.如果没变正常执行,如果有变事务取消
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class RushToBuyTX {
public static void main(String[] args) {
//线程池
ExecutorService executorService = Executors.newFixedThreadPool(100);
//Redis服务器
Jedis jedis = new Jedis("127.0.0.1",6379);
//5000个商品
jedis.set("goodsCount","5000");
//删除 Redis中的 setsucc setfail
jedis.del("setsucc","setfail");
for (int i =0 ;i<100000;i++){
executorService.execute(new UserRushBuyThread());
}
executorService.shutdown();
}
static class UserRushBuyThread implements Runnable{
Jedis jedis = new Jedis("127.0.0.1",6379);
int goodsCount = 0;
@Override
public void run() {
try {
//生成UserInfoId;
String userInfoId = UUID.randomUUID().toString();
//监听商品数量
String watchStr = jedis.watch("goodsCount");
//获取商品数量
goodsCount = Integer.parseInt(jedis.get("goodsCount"));
//如果商品数量大于0 可抢购
if (goodsCount > 0) {
//开始事务处理
Transaction transaction = jedis.multi();
//事务处理 商品数量减少1
transaction.decr("goodsCount");
//事务处理 添加一个成功抢购的用户
transaction.sadd("setsucc",userInfoId);
//执行事务 exec会取消watch监听
List<Object> list = transaction.exec();
//如果两个事务都执行成功 那么执行成功数量为2
if (list.size() == 2) {
//添加抢购成功用户Id
System.out.println("用户:" + userInfoId + "抢购成功" + "剩下库存" + jedis.get("goodsCount"));
} else {
System.out.println("用户:" + userInfoId + "抢购失败");
//添加抢购失败用户Id
jedis.sadd("setfail", userInfoId);
}
} else {
//商品已为空 无法启动事务 取消监听
jedis.unwatch("goodsCount");
//添加抢购失败用户Id
System.out.println("用户:" + userInfoId + "抢购失败");
//添加抢购失败用户Id
jedis.sadd("setfail", userInfoId);
System.out.println("已无库存");
return;
}
}catch (Exception e){
e.printStackTrace();
}finally {
jedis.close();
}
}
}
}