alibaba / SmartEngine

SmartEngine is a lightweight business orchestration engine.
Apache License 2.0
760 stars 216 forks source link

启动流程时加锁的锁关键字问题 #29

Closed JannLim closed 3 years ago

JannLim commented 3 years ago

1.流程启动DefaultProcessCommandService.start方法中,业务加锁,此处新增流程实例,然后根据流程实例id加锁,那么不是相同的业务在并发的场景下还是会创建出2个流程实例,这个地方的锁似乎是没有用的。

private void tryInsertProcessInstanceIfNeedLock(ProcessEngineConfiguration processEngineConfiguration,
                                                    ProcessInstance processInstance) {
        LockStrategy lockStrategy = processEngineConfiguration.getLockStrategy();
        if(null != lockStrategy){

            ProcessInstance newProcessInstance =  processInstanceStorage.insert(processInstance, processEngineConfiguration);

            lockStrategy.tryLock(newProcessInstance.getInstanceId());
        }
    }

2.在子流程创建的时候,如果加了锁策略,会导致子流程实例无法创建,代码跑到update方法中去了。

public static ProcessInstance insertAndPersist(ProcessInstance processInstance, Map<String, Object> request,
                                                   ProcessEngineConfiguration processEngineConfiguration) {
        ProcessInstance newProcessInstance ;
        //TUNE 可以在对象创建时初始化,但是这里依赖稍微有点问题
        AnnotationScanner annotationScanner = processEngineConfiguration.getAnnotationScanner();
        ProcessInstanceStorage processInstanceStorage = annotationScanner.getExtensionPoint(
            ExtensionConstant.COMMON,ProcessInstanceStorage.class);
        LockStrategy lockStrategy = processEngineConfiguration.getLockStrategy();
        if(null != lockStrategy){
            newProcessInstance =  processInstanceStorage.update(processInstance, processEngineConfiguration);
        }else{
             newProcessInstance =  processInstanceStorage.insert(processInstance, processEngineConfiguration);
        }
        persisteVariableInstanceIfPossible(request, processEngineConfiguration,
            newProcessInstance, AdHocConstant.DEFAULT_ZERO_VALUE);
        persist(newProcessInstance,processEngineConfiguration);
        return newProcessInstance;
    }
vavi commented 3 years ago
  1. 目前锁的机制的确有较大的优化空间; 一般不建议使用LockStrategy
  2. 问题1,看下传入ProcessInstance#uniqueId 2.问题2,没太明白。
JannLim commented 3 years ago

在并行网关存在的场景下,必须设置LockStrategy,不然ParallelGatewayBehavior(125行)会出现npe。 问题1,将uniqueId作为锁的key锁是可以正常使用的。 问题2,出现的场景是流程中开启了子线程,父线程中出现了并行网关,所以设置了LockStrategy,那么此时进入到子线程之后,由于LockStrategy不为空,所以导致流程实例没有insert操作,子线程执行完成无法回到主线程。 针对于上述两个问题,我这里修复了一版,没有发pr,版本: https://github.com/JannLim/SmartEngine/tree/hotfix-subprocess

vavi commented 3 years ago

好的 我看下哈。