Spring Schedule关闭订单

写一个最简单的版本,因为我们是一个Schedule,不需要返回值,closeOrderTaskV1,第一个版本,那如果其实我们不是

TOMCAT集群的话,我们这一个方法就OK了,但是我们是TOMCAT集群,所以呢,需要创建一个分布式锁,那第一个版本是没有分布式

锁的,非常简单,我们一起来写一下,首先加上@Schedule这么一个注解,这个包是annotation里面的scheduled的,千万不要加错,

然后括号里面写一下,我们需要它每一分钟执行一次,等于什么呢,用引号引一下,cron="0 */1 * * * ?",每个一分钟的整数倍,

然后填充一下他的逻辑

    /**
     * 没有分布式锁,运行起来来看日志。
     */
//    @Scheduled(cron="0 */1 * * * ?")//每1分钟(每个1分钟的整数倍)
    public void closeOrderTaskV1(){
        int hour = Integer.parseInt(PropertiesUtil.getProperty("close.order.task.time.hour","2"));
        iOrderService.closeOrder(hour);
    }
	
public class PropertiesUtil {


    private static Properties props;

    static {
        String fileName = "mmall.properties";
        props = new Properties();
        try {
            props.load(new InputStreamReader(PropertiesUtil.class.getClassLoader()
			.getResourceAsStream(fileName),"UTF-8"));
        } catch (IOException e) {
            log.error("配置文件读取异常",e);
        }
    }

    public static String getProperty(String key){
        String value = props.getProperty(key.trim());
        if(StringUtils.isBlank(value)){
            return null;
        }
        return value.trim();
    }

    public static String getProperty(String key,String defaultValue){

        String value = props.getProperty(key.trim());
        if(StringUtils.isBlank(value)){
            value = defaultValue;
        }
        return value.trim();
    }



}

从配置文件=里面获取这个配置,如果key不存在也是两个小时,那这里面的逻辑就是说,我们获取两个小时,也就是说每一分钟我都会

执行一下,这个定时任务会关闭,以当前时间为准,两个小时之前下单,但是呢,未付款的订单,那为了验证方便呢,我们加一行日志,

关闭订单定时任务启动,说明我们写的Spring Schedule定时任务,是生效的,因为我们的频率比较高,每一分钟要执行一次,

    @Override
    public void closeOrder(int hour) {
        Date closeDateTime= DateUtils.addHours(new Date(),-hour);
        List<Order> orderList = orderMapper.selectOrderStatusByCreateTime(
		Const.OrderStatusEnum.NO_PAY.getCode(),
		DateTimeUtil.dateToStr(closeDateTime));

        for(Order order : orderList){
            List<OrderItem> orderItemList = orderItemMapper.getByOrderNo(order.getOrderNo());
            for(OrderItem orderItem : orderItemList){

                //使用写独占锁,一定要用主键where条件,防止锁表。同时必须是支持MySQL的Innodb。
                Integer stock = productMapper.selectStockByProductId(orderItem.getProductId());

                //考虑到已生成的订单里的产品,被删除的情况
                if(stock == null){
                    continue;
                }
                Product product = new Product();
                product.setId(orderItem.getProductId());
                product.setStock(stock+orderItem.getQuantity());
                productMapper.updateByPrimaryKeySelective(product);
            }
            orderMapper.closeOrderCloseByOrderId(order.getId());
            log.info("关闭订单OrderNo:{}",order.getOrderNo());
        }

    }

这个时候根据订单状态和createTime,开始找到orderList,那orderList我们一共找了755个,找到这订单的OrderItemList,

根据productId拿他的库存,现在表里的库存是995个,这个 时候stock就是995加1,现在我们是单击来关闭没有问题,那如果我们再

启动一个TOMCAT,现在我们要聚焦在分布式任务调度上,这样就造成了一个问题,什么问题,这个定时任务我只希望,在TOMCAT集群

环境下,一个服务执行就可以了,并不需要大家都来执行它,并且如果大家一起执行的话,也浪费了MYSQL和服务器的一个性能,因为其他

机器不需要执行,只执行一台就行,第二个就很容易造成数据错乱,因为大家都在执行SQL语句,那接下来我们就讲使用redis实现分布式

锁的一个原理,来解决这一个问题

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值