运行具有零故障时间的自定义 X++ 脚本

此功能允许您上载和运行包含自定义 X++ 脚本的可部署包,而无需通过 Microsoft Dynamics Lifecycle Services (LCS) 或暂停您的系统。 因此,您可以在不造成任何中断性停机的情况下更正轻微的数据不一致问题。

使用 X++ 脚本更正轻微数据不一致的好处是系统在运行脚本时会根据需要自动调整所有相关表。 这种方法有助于确保更正的完整性,并有助于将引入新的不一致的风险降至最低。

重要

此功能仅用于更正轻微的数据不一致。 不能用于以下目的或任何其他用途:

  • 数据收集
  • 架构更改
  • 数据迁移或其他长期流程
  • 可以通过其他方式进行的数据更正,如常规业务流程、数据一致性工具或其他自助服务工具

此功能允许授权用户直接更改实体及其记录,而无需运行与这些实体关联的业务逻辑。 这些更改可能导致数据完整性问题。 因此,您的组织可能需要您在运行脚本之前和/或之后获得内部和外部审计员(或其他同等利益干系人)的批准和签核。 出于合规原因,影响某些特征的更改也可能必须在外部报表(如财务报表)中披露或向政府当局报告。 您的组织对通过此功能对其数据进行的任何更改、对这些更改的任何批准和签核或披露以及对适用法律的遵守负全部责任。 您承担使用此功能的所有风险。

上载到系统中的所有可部署包都将经过强制性工作流。 作为安全预防措施,同时帮助确保职责划分,上载可部署包的用户不允许批准此包用于工作流的后续步骤。 必须由另一个用户对它进行审批。 但是,在包被批准后,上载包的用户将被允许完成其余步骤。

系统需要所有可部署包都经过测试运行。 在允许脚本在生产数据上运行之前,用户必须通过选择接受测试日志来验证输出是否正确。 如果输出不正确,用户必须通过选择放弃将包标记为失败。 在这种情况下,将不允许对生产数据运行脚本。

每个上载的包都保存在系统中,将会经历定义的事件工作流。 对于每个事件,系统将保留一个日志,其中包括时间戳和执行事件的人员的身份。 这样,系统可以确保存在审核线索。

如下图所示,系统提供有关如何在 X++ 中运行每个可部署包以及涉及哪些实体的详细信息。

脚本详细信息页面。

将责任分配给用户以控制访问权限

此功能提供以下责任。 管理员可以使用这些责任来帮助控制对此功能的访问权限。

  • 维护自定义脚本 – 此责任授予在环境中上载、测试、验证和运行自定义 X++ 脚本的能力(用户验收测试 [UAT] 和生产)。
  • 审核自定义脚本 – 此责任授予审核上载的自定义 X++ 脚本的能力。 审核是测试、验证和运行任何脚本之前的强制性步骤。

为帮助最大程度地降低恶意操作的风险,每个脚本都必须由上载它的用户以外的用户明确审核。 管理员必须先将上述责任分配给至少两个相关的高度可信的用户,然后您才可以在组织中使用此功能。 虽然一个用户可以同时承担这两个责任,但该用户仍然无法审核自己的脚本。

创建可部署包

此功能需要一个常规的可部署包,其可以在 Visual Studio 中创建。 有关说明,请参阅创建模型的可部署包

您的可部署包必须包含一个可运行的 X++ 类。 换句话说,它必须具有一个类,该类包含具有以下签名的方法。

public static void main(Args _args)

注释

主要方法的名称必须是小写的。

代码示例

以下代码示例显示可以如何构造可部署包。

class MyScriptClassForIssueXYZ
{
    public static void main(Args _args)
    {
        if (curExt() != 'DAT')
        {
            throw error("This script must run in the DAT company!");
        }

        ttsbegin;

        MyTable myTable;

        update_recordset myTable
            setting myField = 17
            where myTable.myReference == 'xyz';

        if (myTable.RowCount() != 1)
        {
            throw error("Not updating the expected row!");
        }

        info("Success");
  
        ttscommit;
    }

}

最佳实践

以下列表描述成功编写、实施和运行脚本的一些最佳实践。 此列表没有穷举所有实践,只作为指导之用。

  • 在脚本末尾编写一条成功消息。 这样,您将能够看到脚本运行无异常。
  • 添加交易记录范围的显式处理。
  • 使用现有业务逻辑,如 update() 方法,但不要通过使用 doUpdate()doInsert()doDelete() 方法绕过业务逻辑。 此方法将帮助确保正确处理依赖项数据。 这还将显著降低进一步出现数据不一致的风险。
  • 维护公司上下文。 此方法将公开脚本运行时的常见错误。 例如,它将显示脚本是否在错误的公司运行。
  • 保持让受影响的记录数与您的预期一致。 此方法将发现在准备脚本时数据是否在系统中意外转换。
  • 为每个脚本使用唯一类名称(例如,在名称中包含对工作项的引用)。 此方法将防止上载脚本时出现名称冲突问题。 如果需要对脚本进行新迭代,应务必为其提供新名称。
  • 首先在非生产环境中测试每个脚本。 测试预期影响以及对相关数据的意外负面影响。 确保可能受影响的所有业务流程都可以在之后成功完成并且完全完成。

上载并运行可部署包

使用以下过程上载并运行脚本。

  1. 在财务和运营应用中,转到系统管理 > 定期任务 > 数据库 > 自定义脚本

  2. 选择上载

  3. 选择您如本文前面所述创建的可部署包。 系统将提示您指定脚本的用途。

  4. 脚本现在必须由上载用户以外的用户审核。 审核者必须按照以下步骤操作:

    1. 转到系统管理 > 定期 > 数据库 > 自定义脚本
    2. 选择要审核的脚本,然后选择详细信息
    3. 在操作窗格上,在流程工作流选项卡上的开始组中,选择批准拒绝。 如果您选择批准,脚本将被标记为已批准并解锁以进行测试。 如果您选择拒绝,脚本将被锁定。 在这两种情况下,都会记录事件,并在系统中保留脚本的副本。
  5. 必须对脚本进行测试,以确保它按预期工作。 测试者可以是上载者或审核者,也可以是具有所需权限的第三个用户。 测试者必须按照以下步骤操作:

    1. 转到系统管理 > 定期 > 数据库 > 自定义脚本

    2. 选择要测试的脚本,然后选择详细信息

    3. 在操作窗格上,在流程工作流选项卡的测试程组中,选择运行测试。 脚本将在一个临时事务中运行,系统会在收集各种日志和 SQL 语句时自动中止脚本。

    4. 脚本完成运行后,查看日志,验证结果是否符合您的预期。 按以下步骤之一:

      • 如果您对测试结果满意,在操作窗格的流程工作流选项卡上的测试组中选择接受测试日志以允许运行脚本。 事件日志将反映脚本已经过测试的事实,并指出谁以及何时进行的测试。
      • 如果您对测试结果不满意,在操作窗格的流程工作流选项卡上的结束组中选择放弃,以阻止脚本运行。 系统将保留脚本的副本及其历史记录日志。
  6. 当您确定脚本符合您的预期时,在操作窗格的流程工作流选项卡上的运行组中选择运行来运行它。 此命令与之前的测试运行执行相同的操作,但事务将在结束时提交。

  7. 脚本完成运行后,检查结果,确认脚本按预期工作。 按以下步骤之一:

    • 如果您对结果满意,在操作窗格的流程工作流选项卡上的结束组中选择用途已解决。 事件日志将反映脚本成功运行的事实,并指出谁以及何时验证了脚本。 脚本将进行保存,但现在已锁定,无法再次运行。
    • 如果您对结果不满意,在操作窗格的流程工作流选项卡上的结束组中选择用途未解决。 事件日志将反映脚本未能履行预期用途的事实,并指出谁以及何时运行了脚本。 脚本将进行保存,但现在已锁定,无法再次运行。 但是,系统不会自动撤消脚本操作。 您可能必须编写、导入和运行一个新脚本来撤消失败的脚本对系统造成的影响。

您在最后一步中进行的选择定义脚本的最终状态。 您可以根据需要重复此流程。

通过 LCS 上载并运行可部署包

如前一节所述,您可以将其上传到 LCS 并使用常规过程进行部署,而不是通过财务和运营应用的用户界面部署可部署包。 有关详细信息,请参阅安装来自命令行的可部署包

虽然这种方法限制较少,但它提供的错误保护也较少。 此外,由于它需要重启所有服务器,因此会导致一些停机时间。