shedlock实现分布式锁手工调用

手工调用使用场景:想同时支持redis和jdbc场景,想更灵活调用

使用方法

	//锁任务时长
    private static final int SECOND= 1000;
/**
     * 定时更新任务状态
     */
    @Scheduled(cron="50 * * * * ?")
    public void updateUserTaskAckStatus(){
        try{
            JdbcLockService.startCrontabTask("suncloud-log-updateUserTaskAckStatus",20*SECOND,10*SECOND,()->unicastTaskService.updateUserTaskAckStatus());
        }catch (Exception e){
            log.error("updateUserTaskAckStatus",e);
        }
    }

配置:

@Bean("jdbcTemplateLockProvider")
    public JdbcTemplateLockProvider scheduledMysqlLockConfiguration(DataSource mysqlDataSource) {
        return new JdbcTemplateLockProvider(mysqlDataSource);
    }

核心类JdbcLockService


import com.bin.common.CrontabFunction;
import com.bin.common.utils.DateUtils;
import com.bin.common.utils.SpringBeanUtils;
import lombok.extern.slf4j.Slf4j;
import net.javacrumbs.shedlock.core.LockConfiguration;
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.core.SimpleLock;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;

import java.time.Instant;
import java.util.Date;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import static java.time.temporal.ChronoUnit.MILLIS;

/**jdbc分布式锁调度
 * @Desc
 * @Author zzb
 * @CreateTime 2019/12/9 10:36
 */
@Slf4j
public class JdbcLockService {


    /**提供参数,没有返回值
     * @param name
     * @param lockAtMostLen
     * @param lockAtLeastLen
     * @param supplier
     * @param param
     * @param <T>
     * @throws Exception
     */
    public static <T>  void startSupplierTask(String name, long lockAtMostLen, long lockAtLeastLen, Supplier<T> supplier,T param) throws Exception{
        startTask(name,lockAtMostLen,lockAtLeastLen,null,param,null,supplier,null);
    }

    /**没有参数,没有返回结果
     * @param name
     * @param lockAtMostLen
     * @param lockAtLeastLen
     * @param crontabFunction
     * @throws Exception
     */
    public static  void startCrontabTask(String name, long lockAtMostLen, long lockAtLeastLen, CrontabFunction crontabFunction) throws Exception{
        startTask(name,lockAtMostLen,lockAtLeastLen,crontabFunction,null,null,null,null);
    }

    /**有参数,没返回结果
     * @param name
     * @param lockAtMostLen
     * @param lockAtLeastLen
     * @param consumer
     * @param param
     * @param <T>
     * @throws Exception
     */
    public static <T>  void startConsumerTask(String name, long lockAtMostLen, long lockAtLeastLen, Consumer<T> consumer,T param) throws Exception{
        startTask(name,lockAtMostLen,lockAtLeastLen,null,param,consumer,null,null);
    }


    /**有参数,有返回
     * @param name
     * @param lockAtMostLen
     * @param lockAtLeastLen
     * @param function
     * @param param
     * @param <T>
     * @param <R>
     * @return
     * @throws Exception
     */
    public static <T,R> R  startFunctionTask(String name, long lockAtMostLen, long lockAtLeastLen, Function<T,R>  function,T param) throws Exception{
        return startTask(name,lockAtMostLen,lockAtLeastLen,null,param,null,null,function);
    }


    /**统一任务
     * @param name
     * @param lockAtMostLen
     * @param lockAtLeastLen
     * @param crontabFunction
     * @param param
     * @param consumer
     * @param supplier
     * @param function
     * @param <T>
     * @param <R>
     * @return
     * @throws Exception
     */
    public static  <T,R> R startTask(String name, long lockAtMostLen, long lockAtLeastLen, CrontabFunction crontabFunction, T param, Consumer<T> consumer, Supplier<R> supplier, Function<T, R> function) throws Exception{
        Instant now = Instant.now();
        long st = now.getEpochSecond()*1000;

        String lockAtMostUntilString = DateUtils.format(new Date(st+lockAtMostLen),DateUtils.DATE_TIME_PATTERN);
        String lockAtLeastUntilString = DateUtils.format(new Date(st+lockAtLeastLen),DateUtils.DATE_TIME_PATTERN);

        log.info("start task name={} lockAtMostUntil={} lockAtLeastUntil={}",name, lockAtMostUntilString,lockAtLeastUntilString);
        LockProvider lockProvider = SpringBeanUtils.getBean(JdbcTemplateLockProvider.class);
        if(lockProvider == null){
            throw new NullPointerException("JdbcTemplateLockProvider is null");
        }
        LockConfiguration configuration = new LockConfiguration(name,now.plus(lockAtMostLen, MILLIS),now.plus(lockAtLeastLen, MILLIS));
        Optional<SimpleLock> optional =  lockProvider.lock(configuration);
        if(optional.isPresent()){
            log.info("get task lock success, task name={}",name);
            try{
                if(supplier != null){
                    return supplier.get();
                }else if(function != null){
                    return function.apply(param);
                }else if(consumer != null){
                    consumer.accept(param);
                    return null;
                }else if(crontabFunction != null){
                    crontabFunction.runTask();
                    return null;
                }

            }finally {
                optional.get().unlock();
                long et = System.currentTimeMillis();
                log.info("task unlock, timeLen ={},task name={}",(et-st),name);
            }
        }else{
            log.info("get task lock failure,task name={}",name);
        }
        return null;
    }


}

辅助类:CrontabFunction,SpringBeanUtils

@FunctionalInterface
public interface CrontabFunction {
    void runTask();
}

辅助类:SpringBeanUtils

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

@Component
public class SpringBeanUtils implements BeanFactoryAware {
	private static WebApplicationContext context;
	private static BeanFactory beanFactory;

	/**
	 * 注入BeanFactory实例
	 */
	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		SpringBeanUtils.beanFactory = beanFactory;
	}

	@Autowired
	public void setApplicationContext(WebApplicationContext context) {
		SpringBeanUtils.context = context;
	}

	/**
	 * 根据bean的名称获取相应类型的对象
	 */
	public static Object getBean(String beanName) {
		return beanFactory.getBean(beanName);
	}

	/**
	 * 根据bean的名称获取相应类型的对象,使用泛型,获得结果后,不需要强制转换为相应的类型
	 */
	public static <T> T getBean(Class<T> clazz) {
		return context.getBean(clazz);
	}
	/**
	 * 根据bean的名称获取相应类型的对象,使用泛型,获得结果后,不需要强制转换为相应的类型
	 */
	public static <T> T getBean2(Class<T> clazz) {
		WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
		T bean = wac.getBean(clazz);
		return bean;
	}

	public static WebApplicationContext getApplicationContext() {
		return SpringBeanUtils.context;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值