Synchronization failure during multiple AOS start, impacts the CIL update

Issue description:

Synchronization failure during multiple AOS start, impacts the CIL bits update

The problem is that, since multiple AOSs are trying to do the dbSync operation one or more of them enter into

a deadlock so no other operations on those AOSs could continue, not even client connections.

If dbSync does not complete, deployment of assemblies operation is never executed.

This occurs In \Classes\Application\new method:

           ……………            

    if (session.clientKind() == ClientType::Server && session.sessionId() == 1)

    {

        this.syncApplTables();  //needed to sync neccessary application tables

        // Synchronize the X++ IL assembly

        SysCompileIL::synchronizeAssembly();

             ………………..

 

\Classes\Application\syncApplTables

\Classes\Application\getApplTables

In Line 202,  addTable(tableNum(SecurityRoleAllTasksView)); Causes a failure in SyncApplTables and skips the Assembly synchronization.

It makes only an Error entry in AOS machine Eventvwr, but continue AOS boot without the CIL sync :

Error message entry looks like:

“ 

Object Server 09: Dialog issued for client-less session 1: Cannot execute a data Definition language command on @SYS329072 (SecurityRoleAllTasksView).

The view cannot be created. The underlying table may not exist.

Solution suggestion:

Issue was tracked under bug number DAXSE #3212012 and application Hotfix was released on KB #3030101, though only for the AX 2012 RTM version.

For the AX 2012 R2 and AX 2012 R3, the following code changes could be done on the \Classes\Application\syncApplTables method

Before:

void syncApplTables(boolean _force = false)

{

    List            applTables = this.getApplTables();

    ListEnumerator  enumerator = applTables.getEnumerator();

    ConfigurationKeySet keySet      = new ConfigurationKeySet();   

     void syncTable(TableId tableId)

    {

        this.dbSynchronize(tableId,false, true, false);

    }

  ………….

 

After:

void syncApplTables(boolean _force = false)

{

    #OCCRetryCount

    List            applTables = this.getApplTables();

    ListEnumerator  enumerator = applTables.getEnumerator();

    ConfigurationKeySet keySet      = new ConfigurationKeySet();

    DictTable       dtable;

     void syncTable(TableId tableId)

    {

        dtable =new DictTable(TableId);

         if(dtable && dtable.isView())

        {           

                 try

            {

                this.dbSynchronize(tableId, false, true, false);

            }

              catch(Exception::Deadlock)

            {  

                   retry;

            }

              catch (Exception::Error)

            {               

                    if (xSession::currentRetryCount() >= #RetryNum)

                {

                         throw Exception::Error;

                }

                   else

                {                   

                         retry;

                }

            }

        }   

         else

        {

            this.dbSynchronize(tableId, false, true, false);

        }

      ………………….