This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/isis.git
commit 88ee0c6aea91edffed885b5d9274fa5d160b1bf6 Author: Dan Haywood <[email protected]> AuthorDate: Fri Nov 4 10:46:37 2022 +0000 ISIS-3267: improves RunBackgroundCommands, run each command in its own transaction. Also refine the API of CommandExecutorService, return back a Try<Bookmark> rather than a Bookmark --- .../services/command/CommandExecutorService.java | 31 +++--- .../services/command/CommandOutcomeHandler.java | 8 +- .../command/CommandExecutorServiceDefault.java | 117 +++++++++------------ .../commandlog/applib/dom/CommandLogEntry.java | 7 +- .../applib/job/RunBackgroundCommandsJob.java | 71 +++++++------ .../jobcallables/ReplicateAndRunCommands.java | 3 - 6 files changed, 111 insertions(+), 126 deletions(-) diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/command/CommandExecutorService.java b/api/applib/src/main/java/org/apache/causeway/applib/services/command/CommandExecutorService.java index 4670f2a2c9..2f1569af6e 100644 --- a/api/applib/src/main/java/org/apache/causeway/applib/services/command/CommandExecutorService.java +++ b/api/applib/src/main/java/org/apache/causeway/applib/services/command/CommandExecutorService.java @@ -27,6 +27,7 @@ import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.applib.services.iactn.Interaction; import org.apache.causeway.applib.services.iactnlayer.InteractionContext; import org.apache.causeway.applib.services.user.UserMemento; +import org.apache.causeway.commons.functional.Try; import org.apache.causeway.schema.cmd.v2.CommandDto; import lombok.val; @@ -99,10 +100,10 @@ public interface CommandExecutorService { * persistent equivalent) afterwards (for example, setting its {@link Command#getCommandDto() commandDto} field. * * @param interactionContextPolicy - policy to use - * @param command - the {@link Command} to be executed + * @param command - the {@link Command} to be executed * @return - a bookmark representing the result of executing the command (could be null) */ - Bookmark executeCommand( + Try<Bookmark> executeCommand( InteractionContextPolicy interactionContextPolicy, Command command ); @@ -111,10 +112,10 @@ public interface CommandExecutorService { * Executes the specified command (represented as a {@link CommandDto} using the required {@link InteractionContextPolicy}. * * <p> - * IMPORTANT: THIS METHOD HAS SIGNIFICANT SIDE-EFFECTS. Specifically, the {@link Command} of the executing - * thread (obtained using {@link org.apache.causeway.applib.services.iactn.InteractionProvider} to obtain the - * {@link Interaction}, and then {@link Interaction#getCommand()} to obtain the {@link Command}) will be - * UPDATED to hold the {@link CommandDto} passed in. + * IMPORTANT: THIS METHOD HAS SIGNIFICANT SIDE-EFFECTS. Specifically, the {@link Command} of the executing + * thread (obtained using {@link org.apache.causeway.applib.services.iactn.InteractionProvider} to obtain the + * {@link Interaction}, and then {@link Interaction#getCommand()} to obtain the {@link Command}) will be + * UPDATED to hold the {@link CommandDto} passed in. * </p> * * <p> @@ -123,12 +124,11 @@ public interface CommandExecutorService { * </p> * * @param interactionContextPolicy - policy to use - * @param commandDto - the {@link CommandDto} to be executed - * @param outcomeHandler - callback to handle the result - * + * @param commandDto - the {@link CommandDto} to be executed + * @param outcomeHandler - callback to handle the result * @return - a bookmark representing the result of executing the command (could be null) */ - Bookmark executeCommand( + Try<Bookmark> executeCommand( InteractionContextPolicy interactionContextPolicy, CommandDto commandDto, CommandOutcomeHandler outcomeHandler); @@ -137,12 +137,12 @@ public interface CommandExecutorService { * As per {@link #executeCommand(InteractionContextPolicy, Command)}, with a policy of {@link InteractionContextPolicy#NO_SWITCH no switch}. * * <p> - * Note that this method updates the Command as a side-effect. + * Note that this method updates the Command as a side-effect. * </p> * * @see #executeCommand(InteractionContextPolicy, Command) */ - Bookmark executeCommand( + Try<Bookmark> executeCommand( Command command ); @@ -150,15 +150,14 @@ public interface CommandExecutorService { * As per {@link #executeCommand(InteractionContextPolicy, CommandDto, CommandOutcomeHandler)}, with a policy of {@link InteractionContextPolicy#NO_SWITCH no switch}. * * <p> - * Note that this method has significant side-effects. + * Note that this method has significant side-effects. * </p> * - * @see #executeCommand(InteractionContextPolicy, CommandDto, CommandOutcomeHandler) - * * @param commandDto * @param outcomeHandler + * @see #executeCommand(InteractionContextPolicy, CommandDto, CommandOutcomeHandler) */ - Bookmark executeCommand( + Try<Bookmark> executeCommand( CommandDto commandDto, CommandOutcomeHandler outcomeHandler); diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/command/CommandOutcomeHandler.java b/api/applib/src/main/java/org/apache/causeway/applib/services/command/CommandOutcomeHandler.java index 9e3a175c2d..a8311c9765 100644 --- a/api/applib/src/main/java/org/apache/causeway/applib/services/command/CommandOutcomeHandler.java +++ b/api/applib/src/main/java/org/apache/causeway/applib/services/command/CommandOutcomeHandler.java @@ -34,7 +34,7 @@ public interface CommandOutcomeHandler { @Override public Timestamp getStartedAt() { return null; } @Override public void setStartedAt(final Timestamp startedAt) { } @Override public void setCompletedAt(final Timestamp completedAt) { } - @Override public void setResult(final Try<Bookmark> resultBookmark) { } + @Override public void setResult(final Try<Bookmark> result) { } }; /** @@ -64,8 +64,10 @@ public interface CommandOutcomeHandler { void setCompletedAt(Timestamp completedAt); /** - * Sets the result of the execute, represented as a {@link Bookmark}, on the underlying {@link Command} (or persistent equivalent). + * Handle the result of the execute, represented either as a {@link Bookmark} (success case) or an exception (failure), + * on the underlying {@link Command} (or persistent equivalent). */ - void setResult(Try<Bookmark> resultBookmark); + void setResult(Try<Bookmark> result); + } diff --git a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java index ddae64e1a6..c536c815e0 100644 --- a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java +++ b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java @@ -21,6 +21,7 @@ package org.apache.causeway.core.runtimeservices.command; import java.sql.Timestamp; import java.util.List; import java.util.Optional; +import java.util.function.Consumer; import java.util.regex.Pattern; import java.util.stream.Stream; @@ -28,6 +29,7 @@ import javax.annotation.Priority; import javax.inject.Inject; import javax.inject.Named; +import org.apache.causeway.commons.functional.Try; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -47,7 +49,6 @@ import org.apache.causeway.applib.services.xactn.TransactionService; import org.apache.causeway.applib.util.schema.CommandDtoUtils; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.functional.IndexedFunction; -import org.apache.causeway.commons.functional.Try; import org.apache.causeway.commons.internal.base._NullSafe; import org.apache.causeway.commons.internal.exceptions._Exceptions; import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy; @@ -98,12 +99,12 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { @Inject @Getter final SpecificationLoader specificationLoader; @Override - public Bookmark executeCommand(final Command command) { + public Try<Bookmark> executeCommand(final Command command) { return executeCommand(InteractionContextPolicy.NO_SWITCH, command); } @Override - public Bookmark executeCommand( + public Try<Bookmark> executeCommand( final InteractionContextPolicy interactionContextPolicy, final Command command) { @@ -111,7 +112,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { } @Override - public Bookmark executeCommand( + public Try<Bookmark> executeCommand( final CommandDto dto, final CommandOutcomeHandler outcomeHandler) { @@ -119,7 +120,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { } @Override - public Bookmark executeCommand( + public Try<Bookmark> executeCommand( final InteractionContextPolicy interactionContextPolicy, final CommandDto dto, final CommandOutcomeHandler outcomeHandler) { @@ -127,10 +128,10 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { return doExecute(interactionContextPolicy, dto, outcomeHandler); } - private Bookmark doExecute( + private Try<Bookmark> doExecute( final InteractionContextPolicy interactionContextPolicy, final CommandDto dto, - final CommandOutcomeHandler commandUpdater) { + final CommandOutcomeHandler commandOutcomeHandler) { val interaction = iInteractionLayerTracker.currentInteractionElseFail(); val command = interaction.getCommand(); @@ -138,9 +139,9 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { command.updater().setCommandDto(dto); } - copyStartedAtFromInteractionExecution(commandUpdater); + copyStartedAtFromInteractionExecution(commandOutcomeHandler); - val result = transactionService.callWithinCurrentTransactionElseCreateNew( + Try<Bookmark> result = transactionService.callWithinCurrentTransactionElseCreateNew( () -> { if (interactionContextPolicy == InteractionContextPolicy.NO_SWITCH) { // short-circuit @@ -151,12 +152,30 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { () -> doExecuteCommand(dto)); }); - result.ifFailure(ex->{ - log.warn("Exception when executing : {}", - dto.getMember().getLogicalMemberIdentifier(), ex); - }); + // capture result (success or failure) + commandOutcomeHandler.setResult(result); - return handleOutcomeAndSetCompletedAt(commandUpdater, result); + + // + // also, copy over the completedAt at to the command. + // + // NB: it's possible that there is no priorExecution, specifically if + // there was an exception when performing the action invocation/property + // edit. We therefore need to guard that case. + // + val priorExecution = interaction.getPriorExecution(); + if(priorExecution != null) { + + if (commandOutcomeHandler.getStartedAt() == null) { + // TODO: REVIEW - don't think this can happen ... + // Interaction/Execution is an in-memory object. + commandOutcomeHandler.setStartedAt(priorExecution.getStartedAt()); + } + val completedAt = priorExecution.getCompletedAt(); + commandOutcomeHandler.setCompletedAt(completedAt); + } + + return result; } private void copyStartedAtFromInteractionExecution( @@ -178,18 +197,18 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { dto.getMember().getLogicalMemberIdentifier(), dto.getTimestamp(), dto.getInteractionId()); - final MemberDto memberDto = dto.getMember(); - final String logicalMemberIdentifier = memberDto.getLogicalMemberIdentifier(); + val memberDto = dto.getMember(); + val logicalMemberIdentifier = memberDto.getLogicalMemberIdentifier(); - final OidsDto oidsDto = CommandDtoUtils.targetsFor(dto); - final List<OidDto> targetOidDtos = oidsDto.getOid(); + val oidsDto = CommandDtoUtils.targetsFor(dto); + val targetOidDtoList = oidsDto.getOid(); - final InteractionType interactionType = memberDto.getInteractionType(); + val interactionType = memberDto.getInteractionType(); if(interactionType == InteractionType.ACTION_INVOCATION) { - final ActionDto actionDto = (ActionDto) memberDto; + val actionDto = (ActionDto) memberDto; - for (OidDto targetOidDto : targetOidDtos) { + for (val targetOidDto : targetOidDtoList) { val targetAdapter = valueMarshaller.recoverReferenceFrom(targetOidDto); val objectAction = findObjectAction(targetAdapter, logicalMemberIdentifier); @@ -198,9 +217,9 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { // it will switch the targetAdapter to be the mixedInAdapter transparently val argAdapters = argAdaptersFor(actionDto); - final InteractionHead head = objectAction.interactionHead(targetAdapter); + val interactionHead = objectAction.interactionHead(targetAdapter); - val resultAdapter = objectAction.execute(head, argAdapters, InteractionInitiatedBy.FRAMEWORK); + val resultAdapter = objectAction.execute(interactionHead, argAdapters, InteractionInitiatedBy.FRAMEWORK); // flush any Causeway PersistenceCommands pending // (else might get transient objects for the return value) @@ -222,9 +241,9 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { } } else { - final PropertyDto propertyDto = (PropertyDto) memberDto; + val propertyDto = (PropertyDto) memberDto; - for (OidDto targetOidDto : targetOidDtos) { + for (val targetOidDto : targetOidDtoList) { val targetAdapter = valueMarshaller.recoverReferenceFrom(targetOidDto); @@ -233,7 +252,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { Bookmark.forOidDto(targetOidDto)); } - final OneToOneAssociation property = findOneToOneAssociation(targetAdapter, logicalMemberIdentifier); + val property = findOneToOneAssociation(targetAdapter, logicalMemberIdentifier); val newValueAdapter = valueMarshaller.recoverPropertyFrom(propertyDto); @@ -245,55 +264,19 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { return null; } - private Bookmark handleOutcomeAndSetCompletedAt( - final CommandOutcomeHandler outcomeHandler, - final Try<Bookmark> result) { - - - // - // copy over the outcome - // - outcomeHandler.setResult(result); - - // - // also, copy over the completedAt at to the command. - // - // NB: it's possible that there is no priorExecution, specifically if - // there was an exception when performing the action invocation/property - // edit. We therefore need to guard that case. - // - val interaction = iInteractionLayerTracker.currentInteractionElseFail(); - - final Execution<?, ?> priorExecution = interaction.getPriorExecution(); - if(priorExecution != null) { - - if (outcomeHandler.getStartedAt() == null) { - // TODO: REVIEW - don't think this can happen ... - // Interaction/Execution is an in-memory object. - outcomeHandler.setStartedAt(priorExecution.getStartedAt()); - } - final Timestamp completedAt = - priorExecution.getCompletedAt(); - outcomeHandler.setCompletedAt(completedAt); - } - - return result.getValue().orElse(null); - } - - // ////////////////////////////////////// private static ObjectAction findObjectAction( final ManagedObject targetAdapter, final String logicalMemberIdentifier) throws RuntimeException { - final ObjectSpecification specification = targetAdapter.getSpecification(); + val objectSpecification = targetAdapter.getSpecification(); // we use the local identifier because the fullyQualified version includes the class name. // that is a problem for us if the property is inherited, because it will be the class name of the declaring // superclass, rather than the concrete class of the target that we are inspecting here. val localActionId = localPartOf(logicalMemberIdentifier); - final ObjectAction objectAction = findActionElseNull(specification, localActionId); + val objectAction = findActionElseNull(objectSpecification, localActionId); if(objectAction == null) { throw new RuntimeException(String.format("Unknown action '%s'", localActionId)); } @@ -309,9 +292,9 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { // superclass, rather than the concrete class of the target that we are inspecting here. val localPropertyId = localPartOf(logicalMemberIdentifier); - final ObjectSpecification specification = targetAdapter.getSpecification(); + val objectSpecification = targetAdapter.getSpecification(); - final OneToOneAssociation property = findOneToOneAssociationElseNull(specification, localPropertyId); + val property = findOneToOneAssociationElseNull(objectSpecification, localPropertyId); if(property == null) { throw new RuntimeException(String.format("Unknown property '%s'", localPropertyId)); } @@ -344,7 +327,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService { private Can<ManagedObject> argAdaptersFor(final ActionDto actionDto) { - final Identifier actionIdentifier = valueMarshaller.actionIdentifier(actionDto); + val actionIdentifier = valueMarshaller.actionIdentifier(actionDto); return streamParamDtosFrom(actionDto) .map(IndexedFunction.zeroBased((i, paramDto)-> diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntry.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntry.java index ebe5361a66..fc92c295ac 100644 --- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntry.java +++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntry.java @@ -685,6 +685,7 @@ implements Comparable<CommandLogEntry>, DomainChangeRecord, HasCommandDto { @Programmatic public CommandOutcomeHandler outcomeHandler() { return new CommandOutcomeHandler() { + @Override public java.sql.Timestamp getStartedAt() { return CommandLogEntry.this.getStartedAt(); @@ -701,9 +702,9 @@ implements Comparable<CommandLogEntry>, DomainChangeRecord, HasCommandDto { } @Override - public void setResult(final Try<Bookmark> resultBookmark) { - CommandLogEntry.this.setResult(resultBookmark.getValue().orElse(null)); - CommandLogEntry.this.setException(resultBookmark.getFailure().orElse(null)); + public void setResult(Try<Bookmark> result) { + result.ifSuccess(bookmarkIfAny -> bookmarkIfAny.ifPresent(CommandLogEntry.this::setResult)); + result.ifFailure(CommandLogEntry.this::setException); } }; } diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/job/RunBackgroundCommandsJob.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/job/RunBackgroundCommandsJob.java index 0906fe3dec..f956f97828 100644 --- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/job/RunBackgroundCommandsJob.java +++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/job/RunBackgroundCommandsJob.java @@ -1,10 +1,17 @@ package org.apache.causeway.extensions.commandlog.applib.job; import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; import lombok.val; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.function.Consumer; +import java.util.stream.Collectors; import javax.inject.Inject; @@ -16,10 +23,12 @@ import org.apache.causeway.applib.services.iactnlayer.InteractionContext; import org.apache.causeway.applib.services.iactnlayer.InteractionService; import org.apache.causeway.applib.services.user.UserMemento; import org.apache.causeway.applib.services.xactn.TransactionService; +import org.apache.causeway.applib.util.JaxbUtil; import org.apache.causeway.commons.functional.ThrowingRunnable; import org.apache.causeway.commons.functional.Try; import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntry; import org.apache.causeway.extensions.commandlog.applib.dom.CommandLogEntryRepository; +import org.apache.causeway.schema.cmd.v2.CommandDto; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; @@ -37,6 +46,7 @@ import org.springframework.transaction.annotation.Propagation; @Component @DisallowConcurrentExecution @PersistJobDataAfterExecution +@Log4j2 public class RunBackgroundCommandsJob implements Job { @Inject InteractionService interactionService; @@ -44,8 +54,6 @@ public class RunBackgroundCommandsJob implements Job { @Inject CommandLogEntryRepository<? extends CommandLogEntry> commandLogEntryRepository; @Inject CommandExecutorService commandExecutorService; - private final static JavaSqlJaxbAdapters.TimestampToXMLGregorianCalendarAdapter gregorianCalendarAdapter = new JavaSqlJaxbAdapters.TimestampToXMLGregorianCalendarAdapter();; - public void execute(final JobExecutionContext quartzContext) { val user = UserMemento.ofNameAndRoleNames("scheduler_user", "admin_role"); val interactionContext = InteractionContext.builder().user(user).build(); @@ -56,40 +64,35 @@ public class RunBackgroundCommandsJob implements Job { @Override public void run() { - transactionService.runTransactional(Propagation.REQUIRES_NEW, () -> { - val notYetStartedEntries = commandLogEntryRepository.findBackgroundAndNotYetStarted(); - for (val commandLogEntry : notYetStartedEntries) { - val commandDto = commandLogEntry.getCommandDto(); - commandExecutorService.executeCommand(CommandExecutorService.InteractionContextPolicy.NO_SWITCH, commandDto, new OutcomeHandler(commandLogEntry)); - } - }).ifFailureFail(); + // we obtain the list of Commands first; we use their CommandDto as it is serializable across transactions + val commandDtosIfAny = + transactionService.callTransactional( + Propagation.REQUIRES_NEW, + () -> commandLogEntryRepository.findBackgroundAndNotYetStarted() + .stream() + .map(CommandLogEntry::getCommandDto) + .collect(Collectors.toList()) + ) + .ifFailureFail() // we give up if unable to find these + .getValue(); // the success case wrapped in an optional + + // for each command, we execute within its own transaction. Failure of one should not impact the next. + commandDtosIfAny.ifPresent( + commandDtos -> { + for (val commandDto : commandDtos) { + transactionService.runTransactional(Propagation.REQUIRES_NEW, () -> { + // it's necessary to look up the CommandLogEntry again because we are within a new transaction. + val commandLogEntryIfAny = commandLogEntryRepository.findByInteractionId(UUID.fromString(commandDto.getInteractionId())); + + // finally, we execute + commandLogEntryIfAny.ifPresent(commandLogEntry -> + commandExecutorService.executeCommand( + CommandExecutorService.InteractionContextPolicy.NO_SWITCH, commandDto, commandLogEntry.outcomeHandler())); + }).ifFailure(throwable -> log.error("Failed to execute command: " + JaxbUtil.toXml(commandDto), throwable)); + } + }); } } - @RequiredArgsConstructor - private class OutcomeHandler implements CommandOutcomeHandler { - - private final CommandLogEntry commandLogEntry; - - @Override - public Timestamp getStartedAt() { - return commandLogEntry.getStartedAt(); - } - - @Override - public void setStartedAt(Timestamp startedAt) { - commandLogEntry.setStartedAt(startedAt); - } - - @Override - public void setCompletedAt(Timestamp completedAt) { - commandLogEntry.setCompletedAt(completedAt); - } - - @Override - public void setResult(Try<Bookmark> resultBookmark) { - resultBookmark.ifSuccess(bookmarkIfAny -> bookmarkIfAny.ifPresent(commandLogEntry::setResult)); - } - } } diff --git a/incubator/extensions/core/commandreplay/secondary/src/main/java/org/apache/causeway/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java b/incubator/extensions/core/commandreplay/secondary/src/main/java/org/apache/causeway/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java index 500ad84d10..c33211c5d0 100644 --- a/incubator/extensions/core/commandreplay/secondary/src/main/java/org/apache/causeway/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java +++ b/incubator/extensions/core/commandreplay/secondary/src/main/java/org/apache/causeway/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java @@ -164,10 +164,7 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> { return; } } - }); - - } private ReplayState executeCommandInTranAndAnalyse(final CommandLogEntry commandLogEntry) {
