关键字:并发冲突,申请互斥锁失败
场景:保存、提交、审核、反审核、撤销、删除等6个操作时
原因:3.0增加了反写网控功能,避免并发反写源单导致冲突。单据头、单据体都要反写同一个源单,导致冲突。
具体报错:
kd.bos.exception.KDBizException: 并发冲突,反写【询价单】申请互斥锁失败,请稍后再试。 at kd.bos.service.botp.track.bizentity.SourceBillInfo.doStartNetworkCtrl(SourceBillInfo.java:530) at kd.bos.service.botp.track.bizentity.SourceBillInfo.startNetworkCtrl(SourceBillInfo.java:459) at kd.bos.service.botp.track.WriteBackEngine.startNetworkCtrl(WriteBackEngine.java:442) at kd.bos.service.botp.track.WriteBackEngine.doWriteBack(WriteBackEngine.java:98) at kd.bos.service.botp.track.actions.ExecuteWriteLogicAction.execWriteLogicUnit(ExecuteWriteLogicAction.java:111) at kd.bos.service.botp.track.actions.ExecuteWriteLogicAction.doAction(ExecuteWriteLogicAction.java:53) at kd.bos.service.botp.track.actions.AbstractTrackAction.action(AbstractTrackAction.java:60) at kd.bos.service.botp.track.actions.BFTrackBatchExecuter.doActions(BFTrackBatchExecuter.java:116) at kd.bos.service.botp.track.BFTracker.batchExecuteSync(BFTracker.java:186) at kd.bos.service.botp.track.BFTracker.executeLinkItem(BFTracker.java:137) at kd.bos.service.botp.track.BFTracker.execute(BFTracker.java:89) at kd.bos.service.botp.track.WriteBacker.execute(WriteBacker.java:31) at kd.bos.service.botp.track.BFTrackerEngine.execute(BFTrackerEngine.java:218) at kd.bos.service.operation.Audit.afterUpdateBillStatus(Audit.java:66) at kd.bos.service.operation.StatusConvertOperateService.beforeCallOperationTransaction(StatusConvertOperateService.java:71) at kd.bos.service.operation.EntityOperateService.doExcete(EntityOperateService.java:580) at kd.bos.service.operation.EntityOperateService.excute(EntityOperateService.java:328) at kd.bos.service.operation.EntityOperateService.excute(EntityOperateService.java:420) at kd.bos.service.operation.OperationServiceImpl.localInvokeOperation(OperationServiceImpl.java:68) at kd.bos.service.operation.OperationServiceImpl.invokeOperation(OperationServiceImpl.java:42) at sun.reflect.GeneratedMethodAccessor1031.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at kd.bos.service.DispatchServiceImpl.invoke(DispatchServiceImpl.java:53) at sun.reflect.GeneratedMethodAccessor285.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at kd.bos.mservice.rpc.dubbo.debug.LocalDebugProxy$1.lambda$invoke$0(LocalDebugProxy.java:61) at kd.bos.mservice.rpc.dubbo.debug.DubboDebugUtil.invoke(DubboDebugUtil.java:49) at kd.bos.mservice.rpc.dubbo.debug.LocalDebugProxy$1.invoke(LocalDebugProxy.java:58) at com.sun.proxy.$Proxy40.invoke(Unknown Source) at kd.bos.servicehelper.DispatchServiceHelper.invokeBOSService(DispatchServiceHelper.java:98) at kd.bos.servicehelper.operation.OperationServiceHelper.executeOperate(OperationServiceHelper.java:62) at kd.bos.workflow.relservice.BusinessLogicServiceHelper.idepotentExecute(BusinessLogicServiceHelper.java:259) at kd.bos.workflow.relservice.BusinessLogicServiceHelper.execute(BusinessLogicServiceHelper.java:199) at kd.bos.workflow.relservice.BusinessLogicServiceHelper.invokeOperationServiceAsyc(BusinessLogicServiceHelper.java:137) at kd.bos.workflow.relservice.BusinessLogicServiceHelper.invokeOperationService(BusinessLogicServiceHelper.java:57) at kd.bos.workflow.relservice.BusinessLogicServiceHelper.invokeOperationService(BusinessLogicServiceHelper.java:66) at kd.bos.workflow.engine.extitf.ExtItfOperationExecutor.execute(ExtItfOperationExecutor.java:43) at kd.bos.workflow.engine.extitf.ExternalInterfaceUtil.executeExtItf(ExternalInterfaceUtil.java:60) at kd.bos.workflow.engine.impl.util.AutoTaskUtil.handleOperation(AutoTaskUtil.java:73) at kd.bos.workflow.engine.impl.util.AutoTaskUtil.executeExternalInterface(AutoTaskUtil.java:39) at kd.bos.workflow.engine.impl.bpmn.behavior.AutoTaskActivityBehavior.execute(AutoTaskActivityBehavior.java:42) at kd.bos.workflow.engine.impl.agenda.ContinueProcessOperation.executeActivityBehavior(ContinueProcessOperation.java:275) at kd.bos.workflow.engine.impl.agenda.ContinueProcessOperation.executeSynchronous(ContinueProcessOperation.java:201) at kd.bos.workflow.engine.impl.agenda.ContinueProcessOperation.continueThroughFlowNode(ContinueProcessOperation.java:156) at kd.bos.workflow.engine.impl.agenda.ContinueProcessOperation.run(ContinueProcessOperation.java:98) at kd.bos.workflow.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:86) at kd.bos.workflow.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:59) at kd.bos.workflow.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:44) at kd.bos.workflow.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:63) at kd.bos.workflow.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:28) at kd.bos.workflow.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:44) at kd.bos.workflow.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:39) at kd.bos.workflow.engine.impl.asyncexecutor.ExecuteAsyncRunnable.run(ExecuteAsyncRunnable.java:48) at kd.bos.workflow.engine.impl.asyncexecutor.schedule.WfJobHandler.execute(WfJobHandler.java:131) at kd.bos.schedule.api.AbstractJobHandler.handle(AbstractJobHandler.java:25) at kd.bos.schedule.message.JobProcessor.executeTask(JobProcessor.java:260) at kd.bos.schedule.message.JobProcessor.process(JobProcessor.java:197) at kd.bos.schedule.message.JobProcessor.call(JobProcessor.java:344) at kd.bos.schedule.message.JobProcessor.call(JobProcessor.java:45) at kd.bos.threads.impl.ThreadPoolImpl.lambda$submit$1(ThreadPoolImpl.java:79) at kd.bos.thread.ThreadLifeCycleManager$CallableWrap.call(ThreadLifeCycleManager.java:214) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
解决方案:
情况A:如果是单纯的多单反写同一单导致的冲突,多单反写网控冲突,等其他单据处理完毕,再重新处理失败单据时,就不会不再报冲突了,这种情况比较简单,平台优化了延时重试机制,会自动重试多次,直到其他人都处理完,就自动成功执行了,该问题需升级补丁
情况B:A 单 下推 B,B单审核时,先反写A ,然后接着再自动生成 C 并保存,C保存时也反写A,这个逻辑就咬死了。 需要调整插件代码,把自动生成C的逻辑,放在反写A完毕,事务提交之后处理
情况C:如果重试还是能复现,单据下推的时候,是以单据体为主实体,反写源单单据体分录字段。 但二开插件,为单据头也创建了一套关联数据。 在反写时,先后按单据体、单据头反写源单,都会申请网控,在反写单据头时,因为源单网控还没有释放,再申请网控也会失败。 这个也是需要插件设置跳过网控才能解决
现场需要执行下面操作,可以快速配置下面的操作脚本插件解决,具体步骤如下:
下游单据的保存按钮操作代码里面,添加操作插件
插件里面增加一个操作自定义参数,跳过反写网控,this.getOption().setVariableValue("mutex_writeback", "false"); 设置为false,不网控,创建KDE脚本可参考文章:KDE脚本简单入门,以操作插件为例
var plugin = new OperationPlugin({ beforeExecuteOperationTransaction : function(e){ this.getOption().setVariableValue("mutex_writeback", "false"); }});
更多问题:
Q:这样配置,会不会导致单据所有操作都没有网络控制了。
A:反写网控是单独的,只和反写冲突,和其他操作不冲突
推荐阅读