流水可重试回滚框架

package com.example.demo.framework.ability;

import com.example.demo.framework.model.AbilityAnnotation;
import com.example.demo.framework.model.ProductAnnotation;

@ProductAnnotation(productType = "animallife")
public class AnimalLifeProduct {

    @AbilityAnnotation(abilityType = "eat")
    public void eat(){
        System.out.printf("animal eat");
    }

    @AbilityAnnotation(abilityType = "sleep")
    public void sleep(){
        System.out.println("animal sleep");
    }
}
package com.example.demo.framework.ability;

import com.example.demo.framework.model.AbilityAnnotation;
import com.example.demo.framework.model.ProductAnnotation;

@ProductAnnotation(productType = "life")
public class LifeProduct {

    @AbilityAnnotation(abilityType = "eat")
    public void eat(){
        System.out.printf("common eat");
    }

    @AbilityAnnotation(abilityType = "sleep")
    public void sleep(){
        System.out.println("common sleep");
    }

}
package com.example.demo.framework.factory;

import com.example.demo.framework.model.AbilityContext;

public interface AFactory {

    void  eat(AbilityContext abilityContext);

    void sleep(AbilityContext abilityContext);
}
package com.example.demo.framework.factory;

import com.example.demo.framework.ProductPipeline;
import com.example.demo.framework.model.AbilityContext;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component("AnimalFactory")
public class AnimalFactory implements AFactory{

    @Autowired
    private ProductPipeline productPipeline;

    @Override
    public void eat(AbilityContext abilityContext) {
        List abilitys=new ArrayList<>();
        abilitys.add(Pair.of("animallife","eat"));
        productPipeline.executeAbilityList(abilityContext,abilitys);
    }

    @Override
    public void sleep(AbilityContext abilityContext) {
        List abilitys=new ArrayList<>();
        abilitys.add(Pair.of("animallife","sleep"));
        productPipeline.executeAbilityList(abilityContext,abilitys);
    }
}
package com.example.demo.framework.factory;

import com.example.demo.framework.ProductPipeline;
import com.example.demo.framework.model.AbilityContext;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component("HumanAFactory")
public class HumanAFactory implements AFactory{

    @Autowired
    private ProductPipeline productPipeline;
    @Override
    public void eat(AbilityContext abilityContext) {
        List abilitys=new ArrayList<>();
        abilitys.add(Pair.of("life","eat"));
        productPipeline.executeAbilityList(abilityContext,abilitys);
    }

    @Override
    public void sleep(AbilityContext abilityContext) {
        List abilitys=new ArrayList<>();
        abilitys.add(Pair.of("life","sleep"));
        productPipeline.executeAbilityList(abilityContext,abilitys);
    }
}
package com.example.demo.framework.model;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AbilityAnnotation {
    String abilityType();
}
package com.example.demo.framework.model;

public class AbilityContext {
}
package com.example.demo.framework.model;

import org.springframework.stereotype.Component;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
public @interface ProductAnnotation {

    String productType();
}
package com.example.demo.framework;

import com.example.demo.framework.model.AbilityAnnotation;
import com.example.demo.framework.model.AbilityContext;
import com.example.demo.framework.model.ProductAnnotation;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Component
public class ProductPipeline  implements ApplicationListener<ContextRefreshedEvent> {


    private static final Map<String, Map<String,AbliityEntry>> PRODUCT_ABILITY_MAP=new HashMap<>();

    private static ApplicationContext applicationContext;

    private CommonBizProcessTemplate commonBizProcessTemplate;


public  void executeAbilityiesWithLog(AbliityContext context,boolean needRetryTask,boolean needRollBack,List<Pair<String,String>){

commonBizProcessTemplate.executeWithLog(new CommonBizCallBack(){

 protected booelan preCheck(){

   // 根据业务id获取所有进行中的流水,互斥校验


}

protected inirBizLog(){

  return new CommonLogmodel();
}

protect void process(){

List<Pair<String,String>> executeMap=new ArrayList<>();

try{

for(Pair<String,String> entry:abilityMap){
            if(StringUtils.isBlank(entry.getKey())||StringUtils.isBlank(entry.getValue())){
                continue;
            }
            executeAbility(abilityContext,entry.getValue(),entry.getKey());
executeMap.add(entry);
        }

}catch(BizException e)
if(e.getNeedReyry()&&needRetryTask){

saveFailedScene(getRemainAbliites(abilityMap,executeMap));
}

if(!e.getNeedReyry()){

if(needRollBack){

sendRollbackMsg(commonLog);

}
throw e;

}

}catch(Exception){

if(needRetryTask){

saveFailedScene(getRemainAbliites(abilityMap,executeMap));
throw e;
}

}



})
   


}


priavte void saveFailScene(List<String> remainAbilities,AbiolityContext context){

if(remainAbilities==null){
return;
}
TaskModel taskModel=new taskModel();
taskModel.setTaskStatus(INIT);
taskMode.setRetryCnt(0);
taskModel.setGmtFire(new Date());
taskModel.setbizId()
taskModel.seyBizType();
taskMode.setTaskParam(remainAbilities)
taskManager.registerTask(TaskModel);

}


private List<String> getRemainAbliites(List<Pair<String,String>> avilityMap,List<Pair<String,String>> executeMap){
List<String> remainAbilityies=new ArrayList();
if(executeMap.size()!=avilityMap.size()){
 for(<Pair<String,String> entry:avilityMap){
if(executeMap.contains(entry)){
continue;
}
remainAbilityies.add(entry.getKey()+":"+entry.getValue());
}
}
return remainAbilityies;

}



    public void executeAbilityList(AbilityContext abilityContext, List<Pair<String,String>> abilityMap){
        if(CollectionUtils.isEmpty(abilityMap)){
            return;
        }
        for(Pair<String,String> entry:abilityMap){
            if(StringUtils.isBlank(entry.getKey())||StringUtils.isBlank(entry.getValue())){
                continue;
            }
            executeAbility(abilityContext,entry.getValue(),entry.getKey());
        }
    }

    private void executeAbility(AbilityContext abilityContext, String abilityType, String productType) {

        if(PRODUCT_ABILITY_MAP==null){
            return;
        }
        Map<String, AbliityEntry> abilitys = PRODUCT_ABILITY_MAP.get(productType);
        if(abilitys==null){
            //抛异常
        }
        AbliityEntry abliityEntry = abilitys.get(abilityType);

        try{
            Object product=applicationContext.getBean(abliityEntry.productBean);
            abliityEntry.getAbilityMethod().invoke(product,abilityContext);
        }catch (Exception e){

        }

    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if(event.getApplicationContext().getParent()!=null){
            return;
        }
        try{
            Map<String,Object> objectMap=event.getApplicationContext().getBeansWithAnnotation(ProductAnnotation.class);
            if(objectMap!=null&&objectMap.size()!=0){
                for(Map.Entry<String,Object> entry:objectMap.entrySet()){
                    Object extProduct=entry.getValue();
                    if(Objects.isNull(extProduct)){
                        continue;
                    }
                    ProductAnnotation productAnnotation= AnnotationUtils.findAnnotation(extProduct.getClass(),ProductAnnotation.class);
                    if(Objects.isNull(productAnnotation)){
                        continue;
                    }
                    String productType=productAnnotation.productType();
                    Map<String, AbliityEntry> abilitys = PRODUCT_ABILITY_MAP.get(productType);
                    if(abilitys==null){
                        abilitys=new HashMap<>();
                    }
                    Method[] methods=extProduct.getClass().getMethods();
                    for(Method method:methods){
                        if(method.isAnnotationPresent(AbilityAnnotation.class)) {
                            AbilityAnnotation abilityAnnotation=method.getAnnotation(AbilityAnnotation.class);
                            if(Objects.isNull(abilityAnnotation)&&abilityAnnotation.abilityType()!=null){
                                AbliityEntry abliityEntry=new AbliityEntry();
                                abliityEntry.setProductBean(entry.getKey());
                                abliityEntry.setAbilityMethod(method);
                                abilitys.put(abilityAnnotation.abilityType(),abliityEntry);
                            }
                        }
                    }
                    PRODUCT_ABILITY_MAP.put(productType,abilitys);
                }
            }
             applicationContext=event.getApplicationContext();
        }catch (Exception e){
            throw e;
        }

    }


    class AbliityEntry{
        String productBean;

        Method abilityMethod;

        public String getProductBean() {
            return productBean;
        }

        public void setProductBean(String productBean) {
            this.productBean = productBean;
        }

        public Method getAbilityMethod() {
            return abilityMethod;
        }

        public void setAbilityMethod(Method abilityMethod) {
            this.abilityMethod = abilityMethod;
        }
    }
}
package com.example.demo.task;

import com.example.demo.task.model.ExecuteModeEnum;
import com.example.demo.task.model.TaskContext;

import java.util.List;

public interface TaskEngine {

    String registerAndTrigger(TaskContext taskContext);

    String register(TaskContext taskContext);

    void trigger(TaskContext taskContext);

    void trigger(String taskId, ExecuteModeEnum executeMode);

    void batchTrigger(List<String> taskIds, ExecuteModeEnum executeModeEnum);
}
package com.example.demo.task;

import com.example.demo.task.model.TaskContext;

public interface TaskExecutor {

    void  execute(TaskContext taskContext);

    boolean support(TaskContext taskContext);
}
package com.example.demo.task;

import com.example.demo.task.model.TaskStrategy;

import java.util.Date;

public class TaskHelper {

    public static Date computeRetryFireTime(TaskStrategy taskStrategy){

        int interval= taskStrategy.getInterval();
        Date gmtNextFire=new Date(System.currentTimeMillis() + (interval*60*1000));
        return gmtNextFire;
    }

}
package com.example.demo.task;

import com.example.demo.task.model.TaskModel;

public interface TaskRepositiry {

    String insertTask(TaskModel taskModel);

    TaskModel lockByTaskId(String taskId);

    int updateStatus(TaskModel taskModel);

    TaskModel getTaskById(String taskId);
}
package com.example.demo.task.model;

public class CommonTaskParam {

    private String requestId;

    public String getRequestId() {
        return requestId;
    }

    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }
}
package com.example.demo.task.model;

import org.apache.commons.lang3.StringUtils;

public enum ExecuteModeEnum {

    SYNC("SYNC","同步"),

    ASYNC("ASYNC","异步"),
;


    private String code;

    private String desc;

    public static ExecuteModeEnum getByCode(String code){
        if(StringUtils.isBlank(code)){
            return null;
        }
        for(ExecuteModeEnum modeEnum:values()){
            if(StringUtils.equals(modeEnum.getCode(),code)){
                return modeEnum;
            }
        }
        return null;
    }

    ExecuteModeEnum(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}
package com.example.demo.task.model;

import java.util.Date;

public class Task {

    private String taskId;

    private String uniqueId;

    private String bizId;

    private String bizTaskType;

    private String bizTaskStatus;

    private String taskParam;

    private Date gmtFire;

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public String getUniqueId() {
        return uniqueId;
    }

    public void setUniqueId(String uniqueId) {
        this.uniqueId = uniqueId;
    }

    public String getBizId() {
        return bizId;
    }

    public void setBizId(String bizId) {
        this.bizId = bizId;
    }

    public String getBizTaskType() {
        return bizTaskType;
    }

    public void setBizTaskType(String bizTaskType) {
        this.bizTaskType = bizTaskType;
    }

    public String getBizTaskStatus() {
        return bizTaskStatus;
    }

    public void setBizTaskStatus(String bizTaskStatus) {
        this.bizTaskStatus = bizTaskStatus;
    }

    public String getTaskParam() {
        return taskParam;
    }

    public void setTaskParam(String taskParam) {
        this.taskParam = taskParam;
    }

    public Date getGmtFire() {
        return gmtFire;
    }

    public void setGmtFire(Date gmtFire) {
        this.gmtFire = gmtFire;
    }
}
package com.example.demo.task.model;

public class TaskContext {

    private Task task;

    private ExecuteModeEnum executeMode=ExecuteModeEnum.ASYNC;

    private TaskResult result;

    public Task getTask() {
        return task;
    }

    public void setTask(Task task) {
        this.task = task;
    }

    public ExecuteModeEnum getExecuteMode() {
        return executeMode;
    }

    public void setExecuteMode(ExecuteModeEnum executeMode) {
        this.executeMode = executeMode;
    }

    public TaskResult getResult() {
        return result;
    }

    public void setResult(TaskResult result) {
        this.result = result;
    }
}
package com.example.demo.task.model;

import java.util.Date;

public class TaskModel {

    private String taskId;

    private String uniqueId;

    private String bizId;

    private String bizType;

    private String taskStatus;
    private Integer retryCnt;

    private String machineName;

    private String taskParam;

    private Date gmtFire;

    private String memo;

    private Date gmtCreate;

    private Date gmtModified;

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public String getUniqueId() {
        return uniqueId;
    }

    public void setUniqueId(String uniqueId) {
        this.uniqueId = uniqueId;
    }

    public String getBizId() {
        return bizId;
    }

    public void setBizId(String bizId) {
        this.bizId = bizId;
    }

    public String getBizType() {
        return bizType;
    }

    public void setBizType(String bizType) {
        this.bizType = bizType;
    }

    public String getTaskStatus() {
        return taskStatus;
    }

    public void setTaskStatus(String taskStatus) {
        this.taskStatus = taskStatus;
    }

    public Integer getRetryCnt() {
        return retryCnt;
    }

    public void setRetryCnt(Integer retryCnt) {
        this.retryCnt = retryCnt;
    }

    public String getMachineName() {
        return machineName;
    }

    public void setMachineName(String machineName) {
        this.machineName = machineName;
    }

    public String getTaskParam() {
        return taskParam;
    }

    public void setTaskParam(String taskParam) {
        this.taskParam = taskParam;
    }

    public Date getGmtFire() {
        return gmtFire;
    }

    public void setGmtFire(Date gmtFire) {
        this.gmtFire = gmtFire;
    }

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    public Date getGmtCreate() {
        return gmtCreate;
    }

    public void setGmtCreate(Date gmtCreate) {
        this.gmtCreate = gmtCreate;
    }

    public Date getGmtModified() {
        return gmtModified;
    }

    public void setGmtModified(Date gmtModified) {
        this.gmtModified = gmtModified;
    }
}
package com.example.demo.task.model;

public class TaskResult {

    private boolean success=false;

    private boolean needRetry;

    private String errorCode;

    private String memo;

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public boolean isNeedRetry() {
        return needRetry;
    }

    public void setNeedRetry(boolean needRetry) {
        this.needRetry = needRetry;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }
}
package com.example.demo.task.model;

import org.apache.commons.lang3.StringUtils;

public enum TaskStatusEnum {
    INIT("INIT","初始化"),
    PROCESSING("PROCESSING","处理中"),
    RETRY("RETRY","重试"),
    TIMEOUT("TIMEOUT","超时"),
    SUCCESS("SUCCESS","成功"),
    FAILURE("FAILURE","失败"),
    ;
    private String code;

    private String desc;

    public static TaskStatusEnum getByCode(String code){
        if(StringUtils.isBlank(code)){
            return null;
        }
        for(TaskStatusEnum modeEnum:values()){
            if(StringUtils.equals(modeEnum.getCode(),code)){
                return modeEnum;
            }
        }
        return null;
    }

    TaskStatusEnum(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}
package com.example.demo.task.model;

import java.util.ArrayList;
import java.util.List;

public class TaskStrategy {
    /**
     * 任务超时时间 30天
     */
    private int timeout=30;

    /**
     * 任务最大重试次数
     */
    private int maxRetryCnt=100;

    /**
     * 一次捞取数据行数
     */
    private int maxRow=100;

    /**
     * 业务分片
     */
    private int partitionSize=1;

    /**
     * 重试间隔
     */
    private int interval=1;
    /**
     * 任务处理的时间
     */
    private int maxProcessTime=60;
    /**
     * 任务处理的状态
     */
    private List<String> taskStatus=new ArrayList<>();
    {
        taskStatus.add("INIT");
        taskStatus.add("RETRY");
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public int getMaxRetryCnt() {
        return maxRetryCnt;
    }

    public void setMaxRetryCnt(int maxRetryCnt) {
        this.maxRetryCnt = maxRetryCnt;
    }

    public int getMaxRow() {
        return maxRow;
    }

    public void setMaxRow(int maxRow) {
        this.maxRow = maxRow;
    }

    public int getPartitionSize() {
        return partitionSize;
    }

    public void setPartitionSize(int partitionSize) {
        this.partitionSize = partitionSize;
    }

    public int getInterval() {
        return interval;
    }

    public void setInterval(int interval) {
        this.interval = interval;
    }

    public int getMaxProcessTime() {
        return maxProcessTime;
    }

    public void setMaxProcessTime(int maxProcessTime) {
        this.maxProcessTime = maxProcessTime;
    }

    public List<String> getTaskStatus() {
        return taskStatus;
    }

    public void setTaskStatus(List<String> taskStatus) {
        this.taskStatus = taskStatus;
    }
}
package com.example.demo.task.impl;

import com.example.demo.task.TaskEngine;
import com.example.demo.task.TaskExecutor;
import com.example.demo.task.TaskHelper;
import com.example.demo.task.TaskRepositiry;
import com.example.demo.task.model.*;
import com.example.demo.transaction.TransactionSynchronizationHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ThreadPoolExecutor;

@Component
public class TaskEngineImpl implements TaskEngine {

    @Autowired
    private TaskRepositiry taskRepositiry;

    private TransactionTemplate transactionTemplate;

    @Autowired
    private ThreadPoolExecutor taskExecutor;

    @Autowired
    private List<TaskExecutor> executors;

    private String doRegister(TaskContext taskContext){
        if(Objects.isNull(taskContext)){
            //throw new Exception("");
        }
        if(Objects.isNull(taskContext.getTask())){
            //throw new Exception("");
        }
        Task task=taskContext.getTask();
        TaskResult result=taskContext.getResult();
        if(Objects.isNull(result)){
            result=new TaskResult();
            taskContext.setResult(result);
        }
        try{
            String taskId=transactionTemplate.execute(status->{
                task.setBizTaskType(TaskStatusEnum.INIT.getCode());
                TaskModel taskModel=generateTaskModel(task);
                String newTaskId = taskRepositiry.insertTask(taskModel);
                task.setTaskId(newTaskId);
                return newTaskId;
            });
            setSuccessTaskResult(result,"创建任务成功");
            return taskId;
        }catch (Throwable e){
            setFailTaskResult(result,e,true);
            throw e;
        }
    }

    private void doTrigger(TaskContext taskContext){
        ExecuteModeEnum executeModeEnum=taskContext.getExecuteMode();
        if(ExecuteModeEnum.SYNC==executeModeEnum){
            doExecute(taskContext);
        }else {
            taskExecutor.execute(()->{
                doExecute(taskContext);
            });
        }
    }

    private void doExecute(TaskContext taskContext) {
        long start=System.currentTimeMillis();
        Task task=taskContext.getTask();
        TaskResult result=taskContext.getResult();
        if(Objects.isNull(result)){
            result=new TaskResult();
            taskContext.setResult(result);
        }
        TaskModel taskModel=null;
        try {
            taskModel=getTask(task.getTaskId());
            if(CollectionUtils.isEmpty(executors)){
                //throw new Exception("执行器列表为空");
            }
            Optional<TaskExecutor> executorOptional = executors.stream().filter(executor -> executor.support(taskContext))
                    .findFirst();
            if(!executorOptional.isPresent()){
                //throw new Exception("执行器为空");
            }
            executorOptional.get().execute(taskContext);
            result.setSuccess(true);
        }catch (Throwable e){
            setFailTaskResult(result,e,true);
        }finally {
            doAfterExecute(taskContext);
        }
    }

    private void doAfterExecute(TaskContext taskContext) {
        String taskId=taskContext.getTask().getTaskId();
        transactionTemplate.execute(status->{
            TaskModel taskModel=taskRepositiry.lockByTaskId(taskId);
            TaskStatusEnum taskStatus = TaskStatusEnum.getByCode(taskModel.getTaskStatus());
            if(taskStatus==TaskStatusEnum.FAILURE||taskStatus==TaskStatusEnum.SUCCESS){
                return true;
            };
            TaskResult result=taskContext.getResult();
            if(result.isSuccess()){
                taskModel.setTaskStatus(TaskStatusEnum.SUCCESS.getCode());
                taskRepositiry.updateStatus(taskModel);
            }else {
                boolean needRetry=result.isNeedRetry();
                if(needRetry){
                    TaskStrategy taskStrategy=new TaskStrategy();
                    taskModel.setRetryCnt(taskModel.getRetryCnt()+1);
                    taskModel.setTaskStatus(TaskStatusEnum.RETRY.getCode());
                    taskModel.setGmtFire(TaskHelper.computeRetryFireTime(taskStrategy));
                    taskRepositiry.updateStatus(taskModel);

                }else {
                    taskModel.setTaskStatus(TaskStatusEnum.FAILURE.getCode());
                    taskRepositiry.updateStatus(taskModel);
                }
            }
            return true;
        });
    }


    private TaskModel getTask(String taskId){
        return transactionTemplate.execute(status->{
            TaskModel taskModel=taskRepositiry.lockByTaskId(taskId);
            if(Objects.isNull(taskModel)){
                //throw new Exception("");
            }
            TaskStrategy taskStrategy=new TaskStrategy();
            TaskStatusEnum taskStatusEnum=TaskStatusEnum.getByCode(taskModel.getTaskStatus());
            if(taskStatusEnum==TaskStatusEnum.PROCESSING){
                //throw new Exception("任务正在处理");
            }

            if(taskStatusEnum==TaskStatusEnum.SUCCESS){
                //throw new Exception("任务已经成功了");
            }
            if(!(taskStatusEnum==TaskStatusEnum.INIT || taskStatusEnum==TaskStatusEnum.RETRY)){
                //throw new Exception("任务状态不对不处理");
            }
            //任务超时执行
            if(DateUtils.addDays(taskModel.getGmtCreate(),taskStrategy.getTimeout()).getTime()<System.currentTimeMillis()){
                taskModel.setTaskStatus(TaskStatusEnum.TIMEOUT.getCode());
                taskRepositiry.updateStatus(taskModel);
                //throw new Exception("任务执行超时");
            }
            taskModel.setTaskStatus(TaskStatusEnum.PROCESSING.getCode());
            if(taskRepositiry.updateStatus(taskModel)!=1){
                //throw new Exception("任务状态更新失败");
            }
            return taskModel;

        });
    }


    private void setSuccessTaskResult(TaskResult result,String memo){
        result.setSuccess(true);
        result.setMemo(memo);
    }

    private void setFailTaskResult(TaskResult result,Throwable e,boolean needRetry){
        result.setNeedRetry(needRetry);
        result.setSuccess(false);
        result.setMemo(StringUtils.substring(e.getMessage(),0,1024));
    }

    private TaskModel generateTaskModel(Task task){
        TaskModel taskModel=new TaskModel();
        taskModel.setTaskId(task.getTaskId());
        taskModel.setBizId(task.getBizId());
        taskModel.setBizType(task.getBizTaskType());
        taskModel.setTaskStatus(task.getBizTaskStatus());
        taskModel.setMachineName("");
        taskModel.setUniqueId(task.getUniqueId());
        taskModel.setTaskParam(task.getTaskParam());
        taskModel.setGmtFire(Objects.isNull(task.getGmtFire())?new Date():task.getGmtFire());
        taskModel.setRetryCnt(0);
        return taskModel;
    }

    @Override
    public String registerAndTrigger(TaskContext taskContext) {
        String taskId=doRegister(taskContext);
        if(Objects.nonNull(taskContext.getResult())&&taskContext.getResult().isSuccess()){
            TransactionSynchronizationHelper.doAfterCommit(()->doRegister(taskContext));
        }
        return taskId;
    }

    @Override
    public String register(TaskContext taskContext) {
        return doRegister(taskContext);
    }

    @Override
    public void trigger(TaskContext taskContext) {
        doTrigger(taskContext);
    }

    private TaskModel buidTaskModel(String taskId){
        TaskModel taskModel=taskRepositiry.getTaskById(taskId);
        return taskModel;
    }
    @Override
    public void trigger(String taskId, ExecuteModeEnum executeMode) {
        TaskModel taskModel=buidTaskModel(taskId);
        TaskContext taskContext=new TaskContext();
        Task task=new Task();
        task.setBizId(taskModel.getBizId());
        task.setUniqueId(taskModel.getUniqueId());
        task.setBizTaskType(taskModel.getBizType());
        task.setTaskId(taskModel.getTaskId());
        task.setBizTaskStatus(taskModel.getTaskStatus());
        taskContext.setExecuteMode(executeMode);
        String jsonParam=taskModel.getTaskParam();
        task.setTaskParam(jsonParam);
        taskContext.setTask(task);
        trigger(taskContext);
    }

    @Override
    public void batchTrigger(List<String> taskIds, ExecuteModeEnum executeModeEnum) {
        if(!CollectionUtils.isEmpty(taskIds)){
            taskIds.stream().forEach(taskId->{
                trigger(taskId,executeModeEnum);
            });
        }
    }
}
package com.example.demo.transaction;

public interface AfterCommitCallBack {

    void doAfterCommit();

}
package com.example.demo.transaction;

public interface AfterCompletionCallback {

    void doAfterCompletion();
}
package com.example.demo.transaction;

public class TransactionSynchronizationHelper {

    public static void doAfterCommit(AfterCommitCallBack commitCallBack){
        if(TransactionSynchronizationManager.isActuralTransactionActive()){
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){
                public void afterCommit(){
                    commitCallBack.doAfterCommit();;
                }
            });
        }else {
            commitCallBack.doAfterCommit();
        }
    }

    public static void doAfterCompletion(AfterCompletionCallback commitCallBack){
        if(TransactionSynchronizationManager.isActuralTransactionActive()){
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){
                public void afterCommit(){
                    commitCallBack.doAfterCommit();;
                }
            });
        }else {
            commitCallBack.doAfterCommit();
        }
    }
}
public abstract class CommonBizCallBack{


protected abstract CommonLogModel initBizLog();


protected abstract void process();

protected boolean precheck(){

retrun true;

}

}
@service
public class CommonBizProcessTemplate{


@Autwire
private Transactiontemplate transactiontemplate;

@Autwire
priavte CommonLogRepository commonnLogRepository;


@Autwire
private Message message;

@Autwire
private DistributeLock distributeLock;


public void executeWityLog(CommonBizCallBack callback){


if(!callback,precheck()){
return;

}

CommonLogModel logmodel=callback.initBizLog();
if(logmodel==null){
return;

}
boolean locked=false;
String lockKey=logmodel.getLogId()+"_log";
try{

logModel=createInitLog(callback);
locked=distributeLock.lock(lockKey,30);
if(!locked){
   throw new BizExeption("加锁失败");
}
callback.process();
logmodel.setStatus("SUCCESS");
commonnLogRepository.update(logmodel);
}catch(BizException e){

if(!e.getNeedRetry()){
logModel.setStatus("FAILED");
}
if(StringUtils.isnotblacn(e.getmessage())){

logModel.setMemo(e.getMessage());
}

commonnLogRepository.update(logmodel);


throw el

}
catch(SysException e){
if(StringUtils.isnotblacn(e.getmessage())){

logModel.setMemo(e.getMessage());
}

commonnLogRepository.update(logmodel);


throw e;

}
catch(Exception e){
if(StringUtils.isnotblacn(e.getmessage())){

logModel.setMemo(e.getMessage());
}

commonnLogRepository.update(logmodel);


throw e;

}finally{

if(locked){

distributeLock.unlock(locked);

}
}

}




}
状态 DOING,SUCCESS,FAILURED

public CommonLogModel createInitLog(CommonBizCallBack callBack){

CommonLogModel model=callBack.initBizLog();
model.setStatus(DOING);
mode.setVersion(new Date().getTime());

一查 二判断 三插入
业务属性查询
CommonLogModel queryLog=commonLogRepository.query(bizType,bizId,BizUnique);
if(queryLog!=null){
checkUdmponent(queryLog);
model.setLogId(queryLog.getLogId);

return model;
}

try{
String logId=commonLogRepository.insert(model);
}catch(Exception ){
//解决再次冲突
model=commonLogRepository.query(bizType,bizId,BizUnique);
checkUdmponent(model);
}
return model;

}

public void checkUdmponent(CommonLogModel model){
if(model==null){
 thew new BizException("")
}

if(model.getStats()==SUCCESS){
thew new BizException (IDMPONENT,false);
}

if(model.getStatus==FAILED){
thew new BizException (IDMPONENT,false);

}

}

流水表 common_log

id,uniqueid,bizsource,biz_id,biz_type,bizunique,version,status,extinfo

uk(id)

uk(unqieid,biztype,bizunique)

普通索引(bizid,biztype)

任务表biz_task

id,taskid,uniqueid,bizid,biztype,taskstatus,retrucnt,machinename,taskparam,memo,gmrfire,extinfo,result

uk(taskid)

uk(uniqueid.biztype)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值