diff --git a/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java b/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java index 5af5a4cbf8..9e10f96733 100644 --- a/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java +++ b/source/java/org/alfresco/repo/action/ActionTrackingServiceImpl.java @@ -126,7 +126,7 @@ public class ActionTrackingServiceImpl implements ActionTrackingService recordActionComplete((ActionImpl) action); } - private void recordActionComplete(ActionImpl action) + private void recordActionComplete(final ActionImpl action) { if (logger.isDebugEnabled() == true) { @@ -137,9 +137,55 @@ public class ActionTrackingServiceImpl implements ActionTrackingService action.setExecutionEndDate(new Date()); action.setExecutionStatus(ActionStatus.Completed); action.setExecutionFailureMessage(null); + + // Do we need to update the persisted details? if (action.getNodeRef() != null) { - runtimeActionService.saveActionImpl(action.getNodeRef(), action); + // Make sure we re-fetch the latest action details and save + // this version back into the repository + // (That way, if someone has a reference to the + // action and plays with it, we still save the + // correct information) + final Date startedAt = action.getExecutionStartDate(); + final Date endedAt = action.getExecutionEndDate(); + final NodeRef actionNode = action.getNodeRef(); + + AlfrescoTransactionSupport.bindListener(new TransactionListenerAdapter() + { + public void afterCommit() + { + transactionService.getRetryingTransactionHelper().doInTransaction( + new RetryingTransactionCallback() + { + public Object execute() throws Throwable + { + // Update the action as the system user + return AuthenticationUtil.runAs(new RunAsWork() + { + public Action doWork() throws Exception + { + // Grab the latest version of the + // action + ActionImpl action = (ActionImpl) runtimeActionService + .createAction(actionNode); + + // Update it + action.setExecutionStatus(ActionStatus.Completed); + action.setExecutionFailureMessage(null); + action.setExecutionStartDate(startedAt); + action.setExecutionEndDate(endedAt); + runtimeActionService.saveActionImpl(actionNode, action); + + // All done + return action; + } + }, AuthenticationUtil.SYSTEM_USER_NAME + ); + } + }, false, true + ); + } + }); } // Remove it from the cache, as it's finished diff --git a/source/java/org/alfresco/repo/action/ActionTrackingServiceImplTest.java b/source/java/org/alfresco/repo/action/ActionTrackingServiceImplTest.java index 215524ab83..af90d1256d 100644 --- a/source/java/org/alfresco/repo/action/ActionTrackingServiceImplTest.java +++ b/source/java/org/alfresco/repo/action/ActionTrackingServiceImplTest.java @@ -667,11 +667,18 @@ public class ActionTrackingServiceImplTest extends TestCase 3, actionTrackingService.getExecutingActions(sa13).size() ); + // Let the update change the stored node + UserTransaction txn = transactionService.getUserTransaction(); + txn.begin(); actionTrackingService.recordActionComplete(sa13); actionTrackingService.recordActionComplete(moveAction); + txn.commit(); + Thread.sleep(50); + + // Check assertEquals( 2, actionTrackingService.getAllExecutingActions().size() ); @@ -863,6 +870,12 @@ public class ActionTrackingServiceImplTest extends TestCase assertNull(action.getExecutionFailureMessage()); assertEquals(ActionStatus.Completed, action.getExecutionStatus()); + // Let the update change the stored node + txn.commit(); + txn = transactionService.getUserTransaction(); + txn.begin(); + Thread.sleep(50); + // Now re-load and check the stored one action = runtimeActionService.createAction(actionNode); assertNotNull(action.getExecutionStartDate());