Как запустить набор методов класса с ключевым словом client для запуска в пакетном режиме? - PullRequest
2 голосов
/ 30 марта 2011

Метод run, показанный ниже, относится к классу Tutorial_RunbaseBatch для запуска его в партии.

Я внес следующие изменения:

  1. Изменен метод constructSecurityKeySet в классе SysSecurity до server client static public SecurityKeySet constructSecurityKeySet()

  2. Изменен метод runJobStatic в классе BatchRun до server client static void runJobStatic(recId batchId)

Я знаю о фактечто я не должен играть с базовыми классами, но это просто исследование.Он работал нормально, пока я не добавил следующие разделы кода.

Изменение кода 1:

MenuItemName    menuItemName;
AccessType      act;

Изменение кода 2:

act = securitySet.secureNodeAccessmenuItemName,SysSecurity::accessRecType2UtilElementType(AccessRecordType::MenuItemDisplay)); // Line 24

Теперь я получаю следующую ошибкусообщение после добавления вышеуказанных разделов кода

The server-side impersonated (RunAs) session tried to invoke a method that is available for client-side processing only.
(S)\Classes\Tutorial_RunbaseBatch\run - line 24 
(S)\Classes\BatchRun\runJobStatic - line 62 //which is  batchClass.run();

SecurityKeySet (SystemClass) имеет свойство RunOn , установленное в calledFrom ивыполняется везде, где вызывается объект, который может быть клиент или сервер .Он также имеет зависимости от класса Batchable и BatchRunable .Оба класса имеют свойство RunOn, установленное на calledFrom

Я пытался изменить свойства сервера на классы, но это не сработало

Есть ли в любом случаечтобы этот код работал?

Полный код:

public void run()
{
    SecurityKeySet      securitySet;
    UserGroupId         fromUserGroupId;
    DomainId            domainId;
    MenuItemName        menuItemName;
    AccessType          act;
    ;

    #OCCRetryCount

    fromUserGroupId = "XXXX";
    domainId        = "YYYY";

    if (!this.validate())
        throw error("");

    try
    {
        ttsbegin;
        // this.Update();
        securitySet=SysSecurity::constructSecurityKeySet();//error
        securitySet.loadGroupRights(fromUserGroupId,domainId);
        act = securitySet.secureNodeAccess(menuItemName,SysSecurity::accessRecType2UtilElementType(AccessRecordType::MenuItemDisplay));
        ttscommit;
    }
    catch (Exception::Deadlock)
    {
        retry;
    }
    catch (Exception::UpdateConflict)
    {
        if (appl.ttsLevel() == 0)
        {
            if (xSession::currentRetryCount() >= #RetryNum)
            {
                throw Exception::UpdateConflictNotRecovered;
            }
            else
            {
                retry;
            }
        }
        else
        {
            throw Exception::UpdateConflict;
        }
    }
}

Ответы [ 2 ]

3 голосов
/ 23 мая 2011

Причина выпуска:

Класс

SysSecurity по умолчанию настроен для работы на Client. Изменение метода constructSecurityKeySet на server client static не поможет запустить код на сервере. Вы можете изменить свойство RunOn в классе SysSecurity, но может быть причина, по которой оно установлено на Client. Следовательно, я не рекомендовал бы вариант изменения режима RunOn на Client.

Однако, если вы все еще хотите попробовать запустить код в пакетном режиме. Вы можете прочитать нижеприведенное описание о той же самой ошибке, с которой я столкнулся, и о том, как я решил проблему, используя обходной путь.

Аналогичная проблема:

Я столкнулся с тем же сообщением об ошибке при попытке запустить SalesInvoice отчет в пакетном формате по электронной почте с накладной в формате PDF.

The server-side impersonated (RunAs) session tried to invoke a method that is available for client-side processing only.

Проблема, связанная с моим сценарием, заключалась в том, что в отчете содержалось изображение, и в него включался логотип, связанный с обработкой на стороне клиента, и пакетный процесс не мог справиться с этим во время работы на сервере. Задания, добавленные в пакетный процесс, всегда выполняются на Server.

Выполните следующие шаги в AX, чтобы найти эту информацию.

  1. Перейдите к Basic \ Inquiries \ Batch job
  2. Нажмите пакетное задание
  3. Нажмите View tasks справа, чтобы открыть окно задач
  4. В окне Задачи в столбце Run location должен отображаться Server, где выполняется задание.

Внимание:

Я бы предложил с осторожностью использовать упомянутый ниже подход для обновления данных пакетных заданий в базе данных с помощью запроса T-SQL.

Возможное исправление:

Чтобы выполнить на клиенте задание SalesInvoice, как это делалось в 4.0, в итоге я изменил значение непосредственно в базе данных, используя следующий запрос.

UPDATE dbo.BATCH SET RUNTYPE = 0 WHERE CAPTION = '<Your job caption name...>'

Как только запрос был выполнен для обновления данных пакетного задания, убедитесь, что для столбца Run location в окне Задачи задания установлено значение Client. Когда задание задано для запуска в Client , оно не будет выполняться, пока не будет запущена пакетная обработка. Пакетная обработка может быть запущена путем перехода к Basic \ Periodic \ Batch \ Processing.

0 голосов
/ 15 июня 2011

, если вы хотите, чтобы пакетное задание выполнялось на уровне клиента, переопределите метод runsImpersonated (унаследованный от класса RunBaseBatch) и сделайте так, чтобы он возвращал false:

public boolean runsImpersonated()
{
    return false; // always on the client
}

С уважением.

...