Uploaded image for project: 'PUBLIC - Liferay Portal Community Edition'
  1. PUBLIC - Liferay Portal Community Edition
  2. LPS-122323

DB Partition: background tasks are executed in the incorrect partition

Details

    Description

      When a background task is scheduled for the Company System, like in here:

      https://github.com/liferay/liferay-portal/blob/master/modules/dxp/apps/portal-search-tuning/portal-search-tuning-rankings-web/src/main/java/com/liferay/portal/search/tuning/rankings/web/internal/index/creation/activator/RankingIndexCreationBundleActivator.java#L61

      The background task listener process it (BackgroundTaskMessageListener) and in dB partition, we execute the listener once per company unless we configure it otherwise. Then, since the background task is in the cache, we get it even when we are not in the default company:
      https://github.com/liferay/liferay-portal/blob/master/modules/apps/portal-background-task/portal-background-task-service/src/main/java/com/liferay/portal/background/task/internal/messaging/BackgroundTaskMessageListener.java#L84

      So, we process the task again and again in the incorrect partition getting the following exception:

      ct 15 21:36:55.942 build-4 liferay[liferay-586db4794c-zqhjn] [dxp] ERROR [liferay/background_task-4][ParallelDestination:59] Unable to process message {destinationName=liferay/background_task, response=null, responseDestinationName=null, responseId=null, payload=null, values={companyIds=[Ljava.lang.Long;@7301707f, companyId=39548, groupId=0, backgroundTaskId=40601}}ct 15 21:36:55.942 build-4 liferay[liferay-586db4794c-zqhjn] [dxp] ERROR [liferay/background_task-4][ParallelDestination:59] Unable to process message {destinationName=liferay/background_task, response=null, responseDestinationName=null, responseId=null, payload=null, values={companyIds=[Ljava.lang.Long;@7301707f, companyId=39548, groupId=0, backgroundTaskId=40601}}
      Oct 15 21:36:55.942 build-4 liferay[liferay-586db4794c-zqhjn] com.liferay.portal.kernel.messaging.MessageListenerException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update at com.liferay.portal.kernel.messaging.BaseMessageListener.receive(BaseMessageListener.java:41) at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:74) at com.liferay.portal.messaging.internal.ParallelDestination$1.run(ParallelDestination.java:56) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) at com.liferay.portal.dao.orm.hibernate.event.NestableFlushEventListener.onFlush(NestableFlushEventListener.java:61) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) at com.liferay.portal.spring.hibernate.PortletTransactionManager$TransactionStatusWrapper.reset(PortletTransactionManager.java:260) at com.liferay.portal.spring.hibernate.PortletTransactionManager.commit(PortletTransactionManager.java:63) at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.commit(DefaultTransactionExecutor.java:41) at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:77) at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:57) at com.liferay.portal.service.ServiceContextAdvice.invoke(ServiceContextAdvice.java:60) at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:57) at com.liferay.change.tracking.internal.aop.CTTransactionAdvice.invoke(CTTransactionAdvice.java:72) at com.liferay.portal.spring.aop.AopMethodInvocationImpl.proceed(AopMethodInvocationImpl.java:57) at com.liferay.portal.spring.aop.AopInvocationHandler.invoke(AopInvocationHandler.java:49) at com.sun.proxy.$Proxy537.amendBackgroundTask(Unknown Source) at com.liferay.portal.background.task.internal.BackgroundTaskManagerImpl.amendBackgroundTask(BackgroundTaskManagerImpl.java:124) at com.liferay.portal.background.task.internal.messaging.BackgroundTaskMessageListener.doReceive(BackgroundTaskMessageListener.java:85) at com.liferay.portal.kernel.messaging.BaseMessageListener.doReceive(BaseMessageListener.java:48) at com.liferay.portal.kernel.messaging.BaseMessageListener.receive(BaseMessageListener.java:34) ... 5 moreCaused by: java.sql.BatchUpdateException: Duplicate entry '40601' for key 'PRIMARY' at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.cj.util.Util.handleNewInstance(Util.java:192) at com.mysql.cj.util.Util.getInstance(Util.java:167) at com.mysql.cj.util.Util.getInstance(Util.java:174) at com.mysql.cj.jdbc.exceptions.SQLError.createBatchUpdateException(SQLError.java:224) at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchSerially(ClientPreparedStatement.java:855) at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchInternal(ClientPreparedStatement.java:437) at com.mysql.cj.jdbc.StatementImpl.executeBatch(StatementImpl.java:814) at com.zaxxer.hikari.pool.ProxyStatement.executeBatch(ProxyStatement.java:125) at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeBatch(HikariProxyPreparedStatement.java) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) ... 25 moreCaused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '40601' for key 'PRIMARY' at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:955) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1094) at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchSerially(ClientPreparedStatement.java:834) ... 31 more
      

      Technical resolution:
      One or both:

      1. Execute the BackgroundTaskMessageListener always in one and the proper company not in all (it makes sense because it only processes one task at a time). Be sure that all created messages/tasks have populated the company properly. Review the background status listener too. Maybe we can populate the company when creating the message/task based on the CompanyThreadLocal.
      2. Entity cache should use the companyId as part of the key too to never deliver an entity existing in a different company.

      Attachments

        Issue Links

          Activity

            People

              kevin.valencia Kevin Valencia
              alberto.chaparro Alberto Chaparro
              Kiyoshi Lee Kiyoshi Lee
              Alberto Chaparro Alberto Chaparro
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                20 weeks, 2 days ago

                Packages

                  Version Package
                  7.3.10 DXP FP1
                  7.3.10.1 DXP SP1
                  7.3.6 CE GA7
                  7.3.X
                  7.4.13 DXP GA1
                  7.4.3.33 CE GA33
                  7.4.3.34 CE GA34
                  Master