0
点赞
收藏
分享

微信扫一扫

秒杀场景_多线程异步抢单队列分析与实现_02


秒杀场景_多线程异步抢单队列分析与实现_02_java

文章目录

  • ​​1. 实体​​
  • ​​2. Service改造​​
  • ​​3. 启动类​​
1. 实体

package com.gblfy.entity;

import java.io.Serializable;

/**
* 用户排队抢单信息实体
*/
@Data
public class SkillEntity implements Serializable {
private Long productId;
private String userId;
}

2. Service改造

SkillGoodService

package com.gblfy.service;

import com.gblfy.dao.SkillOrderRepository;
import com.gblfy.entity.SkillEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;

@Service
public class SkillGoodService {
public static final String SKILL_GOODS_PHONE = "SKILL_GOODS_PHONE";
public static final String SKILL_GOODS_LIST = "SKILL_GOODS_LIST";

@Autowired
private RedisTemplate redisTemplate;
@Autowired
private SkillOrderRepository skillOrderRepository;
@Autowired
private ProductService productService;
@Autowired
private MutilThreadOrder mutilThreadOrder;

@Transactional
public void add(Long productId, String userId) throws Exception {
// 先封装对象 并且放入redis 队列
SkillEntity skillEntity=new SkillEntity();
skillEntity.setProductId(productId);
skillEntity.setUserId(userId);
redisTemplate.boundListOps(SKILL_GOODS_LIST).leftPush(skillEntity);
mutilThreadOrder.createOrder();
}
}

新增MutilThreadOrder

package com.gblfy.service;

import com.gblfy.dao.SkillOrderRepository;
import com.gblfy.entity.SkillEntity;
import com.gblfy.entity.SkillGood;
import com.gblfy.entity.SkillOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class MutilThreadOrder {
@Autowired
private ProductService productService;
@Autowired
private SkillOrderRepository skillOrderRepository;
@Autowired
private RedisTemplate redisTemplate;

@Async
public void createOrder() throws Exception {
System.out.println("开始异步抢单");
SkillEntity skillEntity = (SkillEntity) redisTemplate.boundListOps(SkillGoodService.SKILL_GOODS_LIST).rightPop();
if (skillEntity == null) {
return;
}
Long productId = skillEntity.getProductId();
String userId = skillEntity.getUserId();
Thread.sleep(10000);
SkillGood skillGood = productService.getGoodById(productId);
if (skillGood == null) {
throw new Exception("商品已经被抢光拉");
}
if (skillGood.getStockCount() > 0) {
SkillOrder skillOrder = new SkillOrder();
skillOrder.setMoney(skillGood.getCostPrice());
skillOrder.setPayTime(new Date());
skillOrder.setStatus("0");
skillOrder.setUserId(userId);
skillOrder.setCreateTime(new Date());
skillOrder.setSkillId(productId);
skillOrderRepository.save(skillOrder);
skillGood.setStockCount(skillGood.getStockCount() - 1);
redisTemplate.boundHashOps(SkillGoodService.SKILL_GOODS_PHONE).put(skillGood.getId(), skillGood);
System.out.println("成功秒杀 剩余库存:" + skillGood.getStockCount());
}
if (skillGood.getStockCount() <= 0) {
System.out.println("库存已经是负数了:" + skillGood.getStockCount());
redisTemplate.boundHashOps(SkillGoodService.SKILL_GOODS_PHONE).delete(skillGood.getId());
productService.update(skillGood);
}
System.out.println("结束异步抢单");
}
}

3. 启动类

package com.gblfy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
@EnableAsync
public class SkillServApplication {

public static void main(String[] args) {
SpringApplication.run(SkillServApplication.class, args);
}

@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//采用普通的key 为 字符串
template.setKeySerializer(new StringRedisSerializer());
return template;
}

@Bean
@LoadBalanced
public RestTemplate create() {
return new RestTemplate();
}
}


举报

相关推荐

0 条评论