最新消息:ww12345678 的部落格重装上线,希望大家继续支持。

Cleaning up the AIF document log

网络文摘 Kevin Roos 3169浏览

While doing a small AIF project I wrote a small batch class to cleanup the AIF document log because the button on the AifDocumentHistory form can take up a huge amount of time. The first thing I did to write this class is checking out the standard Ax code in the following method ClassesAifMessageManagerclearAllProcessedAndError. This method uses a progress bar and deletes records in batches of 3000 records, this is something we don’t need when running in batch.

The first thing our method needs to do is check if we have access rights to delete.

if (    !hasTableAccess(tablenum(AifMessageLog),    AccessType::Delete)
    ||  !hasTableAccess(tablenum(AifDocumentLog), AccessType::Delete)
    ||  !hasTableAccess(tablenum(AifCorrelation),    AccessType::Delete))
{
    throw error("@SYS113226");
}

The second step is requesting the permission to skip AOS validation.

skipAOS = new SkipAOSValidationPermission();
skipAOS.assert();

The next step is calling all the skip methods, Microsoft does this to make sure that a delete_from doesn’t fall back to row by row deletes.

  • skipAosValidation : Skips all validation methods (validateWrite, validateDelete, validateField)
  • skipDatabaseLog : Prevents SQL from making transactions logs.
  • skipDataMethods : Forces doInsert, doUpdate instead of insert, update.
  • skipDeleteActions : Skips all actions defined under DeleteActions ( For example: Deleting a SalesTable also deletes all referencing MarkupTrans records. )
  • skipDeleteMethod : Forces doDelete instead of delete.
  • skipEvents : Disables a lot of kernel events to increase performance.
aifMessageLog.skipAosValidation(true);
aifMessageLog.skipDatabaseLog(true);
aifMessageLog.skipDataMethods(true);
aifMessageLog.skipDeleteActions(true);
aifMessageLog.skipDeleteMethod(true);
aifMessageLog.skipEvents(true);
 
aifDocumentLog.skipDatabaseLog(true);
aifDocumentLog.skipDataMethods(true);
aifDocumentLog.skipDeleteActions(true);
aifDocumentLog.skipDeleteMethod(true);
//BP Deviation Documented
aifDocumentLog.skipAosValidation(true);
aifDocumentLog.skipEvents(true);
 
aifCorrelation.skipDatabaseLog(true);
aifCorrelation.skipDataMethods(true);
aifCorrelation.skipDeleteActions(true);
aifCorrelation.skipDeleteMethod(true);
//BP Deviation Documented
aifCorrelation.skipAosValidation(true);
aifCorrelation.skipEvents(true);

After these methods we can start deleting the records, I’ve used a utcDateTimeRemove variable to cleanup records after a certain number of days.

delete_from     aifDocumentLog
    exists join aifMessageLog
        where   aifDocumentLog.MessageId        == aifMessageLog.MessageId
        &&      aifMessageLog.createdDateTime   <= utcDateTimeRemove
        &&     (aifMessageLog.Status            == AifMessageStatus::Processed
                                                ||
                aifMessageLog.Status            == AifMessageStatus::Error);
 
delete_from     aifCorrelation
    exists join aifMessageLog
        where   aifCorrelation.MessageId        == aifMessageLog.MessageId
        &&      aifMessageLog.createdDateTime   <= utcDateTimeRemove
        &&     (aifMessageLog.Status            == AifMessageStatus::Processed
                                                ||
                aifMessageLog.Status            == AifMessageStatus::Error);
 
delete_from aifMessageLog
    where   aifMessageLog.createdDateTime       <= utcDateTimeRemove
    &&     (aifMessageLog.Status                == AifMessageStatus::Processed
                                                ||
            aifMessageLog.Status                == AifMessageStatus::Error);

The final step is to revert the code access permission.

CodeAccessPermission::revertAssert();

Source : msdn xRecord class

(this job should never run on a production environment, build an archiving alternative instead)