unnunique opened a new issue, #13577:
URL: https://github.com/apache/dolphinscheduler/issues/13577

   ### Search before asking
   
   - [X] I had searched in the 
[issues](https://github.com/apache/dolphinscheduler/issues?q=is%3Aissue) and 
found no similar issues.
   
   
   ### What happened
   
   1, when i visit the page of workflow definition, it throw an error like 
below:
   
![image](https://user-images.githubusercontent.com/37806259/219534123-795e9945-462a-486f-8f05-64aa8347aeaf.png)
   2, and the error log in the api-server process like below:
   ```log
   [ERROR] 2023-02-10 17:11:33.695 +0800 
org.apache.dolphinscheduler.api.exceptions.ApiExceptionHandler:[53] - 
分页查询工作流定义列表错误
   org.mybatis.spring.MyBatisSystemException: nested exception is 
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or 
null) to be returned by selectOne(), but found: 2
           at 
org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:78)
           at 
org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440)
           at com.sun.proxy.$Proxy124.selectOne(Unknown Source)
           at 
org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:159)
           at 
com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:89)
           at 
com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:61)
           at com.sun.proxy.$Proxy156.queryByDefinitionCodeAndVersion(Unknown 
Source)
           at 
org.apache.dolphinscheduler.api.service.impl.ProcessDefinitionServiceImpl.queryProcessDefinitionListPaging(ProcessDefinitionServiceImpl.java:452)
           at 
org.apache.dolphinscheduler.api.service.impl.ProcessDefinitionServiceImpl$$FastClassBySpringCGLIB$$e8e34ed9.invoke(<generated>)
           at 
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
           at 
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
           at 
org.apache.dolphinscheduler.api.service.impl.ProcessDefinitionServiceImpl$$EnhancerBySpringCGLIB$$bafe9a63.queryProcessDefinitionListPaging(<generated>)
           at 
org.apache.dolphinscheduler.api.controller.ProcessDefinitionController.queryProcessDefinitionListPaging(ProcessDefinitionController.java:481)
           at 
org.apache.dolphinscheduler.api.controller.ProcessDefinitionController$$FastClassBySpringCGLIB$$dc9bf5db.invoke(<generated>)
           at 
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
           at 
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)
           at 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
           at 
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
           at 
org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89)
           at 
org.apache.dolphinscheduler.api.aspect.AccessLogAspect.doAround(AccessLogAspect.java:101)
           at sun.reflect.GeneratedMethodAccessor270.invoke(Unknown Source)
           at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
           at java.lang.reflect.Method.invoke(Method.java:498)
           at 
org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)
           at 
org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624)
           at 
org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72)
           at 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
           at 
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
           at 
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
           at 
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
           at 
org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
           at 
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)
           at 
org.apache.dolphinscheduler.api.controller.ProcessDefinitionController$$EnhancerBySpringCGLIB$$ecade38a.queryProcessDefinitionListPaging(<generated>)
           at sun.reflect.GeneratedMethodAccessor486.invoke(Unknown Source)
           at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
           at java.lang.reflect.Method.invoke(Method.java:498)
           at 
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
           at 
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
           at 
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
           at 
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
           at 
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
           at 
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
           at 
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
           at 
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
           at 
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
           at 
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
           at javax.servlet.http.HttpServlet.service(HttpServlet.java:497)
           at 
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
           at javax.servlet.http.HttpServlet.service(HttpServlet.java:584)
           at 
org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
           at 
org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1631)
           at 
com.github.xiaoymin.swaggerbootstrapui.filter.SecurityBasicAuthFilter.doFilter(SecurityBasicAuthFilter.java:84)
           at 
org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
           at 
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
           at 
com.github.xiaoymin.swaggerbootstrapui.filter.ProductionSecurityFilter.doFilter(ProductionSecurityFilter.java:53)
           at 
org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
           at 
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
           at 
org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
           at 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
           at 
org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
           at 
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
           at 
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
           at 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
           at 
org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
           at 
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
           at 
org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
           at 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
           at 
org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
           at 
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
           at 
org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)
           at 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
           at 
org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
           at 
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
           at 
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
           at 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
           at 
org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
           at 
org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601)
           at 
org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548)
           at 
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
           at 
org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
           at 
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
           at 
org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
           at 
org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
           at 
org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
           at 
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434)
           at 
org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
           at 
org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)
           at 
org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
           at 
org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
           at 
org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349)
           at 
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
           at 
org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:763)
           at 
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
           at org.eclipse.jetty.server.Server.handle(Server.java:516)
           at 
org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:400)
           at 
org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:645)
           at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:392)
           at 
org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
           at 
org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
           at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
           at 
org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
           at 
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
           at 
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
           at 
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
           at 
org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
           at 
org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
           at 
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
           at 
org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
           at java.lang.Thread.run(Thread.java:750)
   Caused by: org.apache.ibatis.exceptions.TooManyResultsException: Expected 
one result (or null) to be returned by selectOne(), but found: 2
           at 
org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:80)
           at sun.reflect.GeneratedMethodAccessor123.invoke(Unknown Source)
           at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
           at java.lang.reflect.Method.invoke(Method.java:498)
           at 
org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426)
           ... 107 common frames omitted
   ```
   
   ### What you expected to happen
   
   I think it is an serious bug for use,  I have a lot of workflow definitions 
in my product enviroment, but now I can not see it any more, what i expect is 
below like this::
   
![image](https://user-images.githubusercontent.com/37806259/219534850-777cc3ad-6d34-4b0f-b923-e1525fda854f.png)
   
   
   ### How to reproduce
   
   1,  I  think it's an concurrency issues when many people modify the same 
workflow definetion.  
   2,  the code below will cause the question.
   In maven module   dolphinscheduler-service,  in file ProcessServiceImpl.java
   ```java 
   /**
        * save processDefinition (including create or update processDefinition)
        */
       @Override
       public int saveProcessDefine(User operator, ProcessDefinition 
processDefinition, Boolean syncDefine, Boolean isFromProcessDefine) {
           ProcessDefinitionLog processDefinitionLog = new 
ProcessDefinitionLog(processDefinition);
           Integer version = 
processDefineLogMapper.queryMaxVersionForDefinition(processDefinition.getCode());
          // ################## here it will cause an concurrent issue 
########################
           int insertVersion = version == null || version == 0 ? 
Constants.VERSION_FIRST : version + 1;
           processDefinitionLog.setVersion(insertVersion);
           processDefinitionLog.setReleaseState(!isFromProcessDefine || 
processDefinitionLog.getReleaseState() == ReleaseState.ONLINE ? 
ReleaseState.ONLINE : ReleaseState.OFFLINE);
           processDefinitionLog.setOperator(operator.getId());
           
processDefinitionLog.setOperateTime(processDefinition.getUpdateTime());
           int insertLog = processDefineLogMapper.insert(processDefinitionLog);
           int result = 1;
           if (Boolean.TRUE.equals(syncDefine)) {
               if (0 == processDefinition.getId()) {
                   result = processDefineMapper.insert(processDefinitionLog);
               } else {
                   processDefinitionLog.setId(processDefinition.getId());
                   result = 
processDefineMapper.updateById(processDefinitionLog);
               }
           }
           return (insertLog & result) > 0 ? insertVersion : 0;
       }
   ```
   3,  in some case it will create two or more log  that have the same code and 
version in table t_ds_process_definition_log, just like below:
   
![image](https://user-images.githubusercontent.com/37806259/219536479-99bfa670-d351-4bb4-b0f6-0f5736be922e.png)
   
   4, also it happen in 3.1.X
   
   ### Anything else
   
   _No response_
   
   ### Version
   
   3.0.x
   
   ### Are you willing to submit PR?
   
   - [ ] Yes I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [X] I agree to follow this project's [Code of 
Conduct](https://www.apache.org/foundation/policies/conduct)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: 
[email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to