Commodity kill is a very common scenario, today we will use Redis to implement the commodity kill function.

Why Redis?

  • Redis is a non-relational database, data is stored in memory, data access is very fast!
  • Redis is single-threaded, and even if there are multiple commands operating on the database at the same time, those commands are still queued.

SpringDataRedis

SpringDataRedis is a Java language implementation of Redis database operation API, it is one of the Frameworks of SpringData series, specifically used to operate Redis, and can be seamlessly integrated with SpringBoot.

How do you do that?

Redis can store five data structures, and we use list data to implement the item kill feature.

  • We take the item information as the key value of the list structure and give the list push value of the number of items in stock.
  • When an item is killed, we use the pop command to retrieve data from the list.

The specific implementation

Setting up the development environment

<! --SpringBoot is the parent project -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.4. RELEASE</version>
</parent>

<dependencies>
    <! -- Test function launcher for integration with junit test function -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <! -- Spring-data-redis initiator -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <! -- Lombox plugin dependency, SpringBoot built-in, do not need to mark the version number -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
Copy the code

The startup class for the SpringBoot project

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) { SpringApplication.run(MyApplication.class); }}Copy the code

Dao layer

  • Dao layer interface
public interface CommodityDao {
    /** * Add goods to stock *@param key
     * @param value
     */
    void addStock(String key,String value);

    /** ** **@param key
     * @return* /
    String spike(String key);
}
Copy the code
  • Dao layer implementation
@Repository
public class CommodityDaoImpl implements CommodityDao {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void addStock(String key,String value) {
        redisTemplate.boundListOps(key).leftPush(value);
    }

    @Override
    public String spike(String key) {
        return(String) redisTemplate.boundListOps(key).leftPop(); }}Copy the code

The Service layer

  • The Service interface layer
public interface CommodityService {
    /** * Add goods to stock *@param stock
     */
    void addStock(int stock);

    /** ** **@return* /
    String spike(a) ;
}
Copy the code
  • The Service layer
@Service
public class CommodityServiceImpl implements CommodityService {

    @Autowired
    private CommodityDao commodityDao;

    private final static String KEY = "commodity";

    @Override
    public void addStock(int stock) {
        for(int i = 0; i < stock; i++) {
            commodityDao.addStock(KEY,"Smart watch"); }}@Override
    public String spike(a) {
        returncommodityDao.spike(KEY); }}Copy the code

Testing capabilities

@SpringBootTest
@RunWith(SpringRunner.class)
public class RedisTest {

    @Autowired
    private CommodityService commodityService;

    /** * 5 items have been stored in the database */
    @Before
    public void addStock(a) {
        commodityService.addStock(5);
    }

    /** * commodity kill test, using two threads together kill */
    @Test
    public void spike(a) {
        ExecutorService es = Executors.newFixedThreadPool(3);
        Object obj = new Object();
        es.submit(() -> {
            System.out.println(Thread.currentThread().getName() + "In the process of killing.");
            while (true) {
                String commodity = commodityService.spike();
                if(commodity ! =null) {
                    System.out.println(Thread.currentThread().getName() + "Got the merchandise." + commodity);
                } else {
                    System.out.println("The merchandise is gone.");
                    break; }}}); es.submit(() -> { System.out.println(Thread.currentThread().getName() +"In the process of killing.");
            while (true) {
                String commodity = commodityService.spike();
                if(commodity ! =null) {
                    System.out.println(Thread.currentThread().getName() + "Got the merchandise." + commodity);
                } else {
                    System.out.println("The merchandise is gone.");
                    break; }}}); }/** ** single-threaded environment seconds */
    @Test
    public void del(a) {
        while (true) {
            String commodity = commodityService.spike();
            if(commodity ! =null) {
                System.out.println(Thread.currentThread().getName() + "Got the merchandise." + commodity);
            } else {
                System.out.println("The merchandise is gone.");
                break; }}}}Copy the code