ALF-3262 - Avoid contention and auth issues when updating the last run details on a previously persisted action run through the action tracking service

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22917 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Nick Burch
2010-10-06 12:33:11 +00:00
parent ae2ee867f1
commit 28dcad6dba
2 changed files with 61 additions and 2 deletions

View File

@@ -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<Object>()
{
public Object execute() throws Throwable
{
// Update the action as the system user
return AuthenticationUtil.runAs(new RunAsWork<Action>()
{
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

View File

@@ -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());