SyncCouponSendNumService.java 2.52 KB
package com.yohoufo.promotion.service;

import com.google.common.collect.Sets;
import com.yohoufo.promotion.common.Constant;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Iterator;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class SyncCouponSendNumService {

    private static final Logger logger = LoggerFactory.getLogger(SyncCouponSendNumService.class);

    /**
     * 是否正在运行,防止任务重复执行
     */
    private static volatile boolean IS_RUNNING = false;

    /**
     * 优惠券ID set集合
     */
    private static Set<String> COUPON_TOKEN_SET = Sets.newConcurrentHashSet();

    @Autowired
    private SingleCentCouponService singleCentSyncCoupNumService;


    public static void addCouponToken(String couponToken) {
        COUPON_TOKEN_SET.add(couponToken);
    }

    /**
     * 前一次任务执行完5分钟后再执行,且任务中又随机睡10分钟,将redis中的领用数量同步到DB中持久化
     */
    @Scheduled(fixedDelay = Constant.SYNC_COUPON_SEND_NUM_REDIS_2_DB)
    public synchronized void syncCouponSendNumRedis2DB() {
        if (IS_RUNNING) {
            logger.info("sync send num to db task is running");
            return;
        }
        try {
            IS_RUNNING = true;
            int sleepSeconds = new Random().nextInt(600);
            logger.info("sync coupon send num just sleep:{}s", sleepSeconds);
            TimeUnit.SECONDS.sleep(sleepSeconds);

            if (CollectionUtils.isEmpty(COUPON_TOKEN_SET)) {
                logger.info("no coupons send num need sync");
            }

            Iterator<String> iterator = COUPON_TOKEN_SET.iterator();
            for (; iterator.hasNext(); ) {
                String couponToken = iterator.next();
                try {

                    if (singleCentSyncCoupNumService.syncCoupSendNum(couponToken)) {
                        iterator.remove();
                    }
                } catch (Exception e) {
                    logger.error("sync coupon send num error:{},{}", couponToken, e.getMessage());
                }
            }
        } catch (Exception e) {
            logger.error("sync send coupon num error:{}", e.getMessage());
        } finally {
            IS_RUNNING = false;
        }
    }

}