脚本编制最佳实践

脚本语言使您能够使用 Python JavaScript, 或任何其他JSR223-compliant脚本语言扩展 Maximo® Manage业务逻辑。 所有脚本代码都编译为 Java™ 字节码,并作为 Maximo Manage 运行时高速缓存的一部分进行高速缓存。 启动脚本时,它是 Java 虚拟机使用 JSR223 网桥运行的高速缓存字节码。 由于脚本代码与其他以 Java 编写的 Maximo Manage 业务逻辑在同一线程中运行,因此编写不好的脚本代码会对系统性能产生负面影响。 遵循 Maximo Manage 性能准则,因为脚本编制等同于 Maximo Manage 定制代码。 我们不支持在脚本中导入任何 Python 模块(.py)。 我们建议改用内置的 Java 库和 Maximo SDK。

选择正确的启动点和活动

启动点是脚本触发点。 通常,选择正确的启动点有助于避免脚本中的某些性能问题。 例如,在先前发行版中,不支持属性值初始化。 这导致许多脚本开发者使用对象启动点 (OLP) 初始化事件来初始化 Maximo 业务对象 (MBO) 属性值。 虽然功能未受影响,但当您选择许多 MBO 时,可能会导致性能问题。 MboSet,选择的每个MBO都会运行OLP初始化事件脚本,即使该脚本初始化的属性没有被使用或显示。 可以通过将对象启动点更改为初始化值事件的属性启动点来避免此问题。 以下样本脚本代码显示 thisvalue 是当前属性 init 值:
if priority is not None:
   thisvalue=2*priority

仅当代码或用户界面引用此属性时, MBO 框架才会启动此脚本。

启动点选择的另一个示例是集成跳过事件。 通常,开发者使用用户出口脚本编制来确定是否需要跳过出站集成消息。 但是,此时系统已经产生了将 MBO 序列化的成本。 而是应该使用发布通道事件过滤器脚本编制,在触发事件时以及在发生 MBO 的任何序列化之前调用此脚本编制。 以下样本显示了用于 MBO 的事件过滤器脚本编制。
if service.getMbo().getString("status")=="APPR":
  evalresult=False
evalresult=True

如果从 "列表" 选项卡调用,请避免代价高昂的对象初始化事件

仅当从 选项卡而不是从 列表 选项卡初始化对象时,您可能希望使用成本高昂的对象初始化脚本。 在 选项卡中,只有一个对象。 在 列表 选项卡中,有许多对象。 在此类情况下,以下样本代码很有用:
from psdi.common.context import UIContext
if UIContext.getCurrentContext() is not None and UIContext.isFromListTab()==False:
    ..costly initialization..

注意有冲突的启动点事件脚本

脚本编制框架允许您将多个脚本附加到同一启动点事件。 如果脚本代码期望在同一启动点事件中的某些其他脚本之前或之后按特定顺序运行该脚本,那么这会产生问题。 由于 Maximo 事件主题是无序映射,因此将在没有固定顺序的情况下触发事件。 如果未正确管理订单依赖关系,那么这可能会导致问题。 您应该评估为同一启动点事件附加多个脚本的原因,并评估将这些脚本组合到一个脚本中是否更有意义。 另一个选项是确保脚本之间没有依赖关系。

避免在事务中间调用保存

此编码模式可能会导致 Maximo Manage 事务和事件触发发生问题。 理想情况下,当事务正在进行时,该脚本应尝试成为包含该事务的一部分。 只要是从脚本启动点 MBO 或任何相关 MBO 创建的 MBO ,由脚本创建或更新的 MBO 就会自动成为包含在内的事务的一部分。 如果您使用 ).getMboSet(“…” 创建MBO,它将在包含事务之外,除非您将其明确添加到以下包含事务中:
mbo.getMXTransaction().add(<newly created a mboset>)

多次调用 MboSet.count ()

编写脚本时常见错误是多次检查 MboSet 的计数。 每次调用 count () 调用时,都会触发 SQL。 更好的方法是调用一次,将值存储在 var 中,然后将该 var 用于后续代码流。 以下示例演示了此方法。
cnt = mboset.count()
if cnt<=1:
  service.log(“skipping this as count is “+cnt)
请勿按以下示例中所示对其进行编码。
if mboset.count()<=1:
  service.log(“skipping this as count is “+mboset.count())

关闭 MboSet

MBO 框架始终会释放在事务完成后创建的 MboSets 。 如果所有 MboSets 都是作为与启动点 MBO 或其任何相关 MBO 的相关集合创建的。 然而,如果 MboSet 是使用 ).getMboSet( 创建的,则脚本代码负责关闭并清除MboSet。 以下示例显示如何清除 MboSet。
try:
  ..some code..
finally:
  mboset.cleanup()

如果不清除 MboSets, ,可能会出现内存不足的错误。

避免使用 Nashorn 的 Mozilla 兼容性脚本

出于性能原因,建议从 Rhino 和 Java 7 移至 Nashorn 和 Java 8。 与 Rhino 相比, Nashorn 在 Java 8 中的性能更好。 将 Mozilla 兼容性脚本与 Nashorn 配合使用可能会导致 Java 8 性能低下。

在日志记录之前检查是否启用了日志记录

日志记录通常在脚本中完成,而不检查日志级别。 以下样本显示了这将如何影响性能:
service.log("count of mbos "+mboset.count())

不幸的是,此代码会导致调用 mboset.count() ,即使已禁用脚本日志记录也是如此。

更好的方法是在调用 mboset.count() 之前检查是否启用了调试。
from psdi.util.logging import MXLoggerFactory
logger = MXLoggerFactory.getLogger("maximo.script");
debugEnabled = logger.isDebugEnabled()

if debugEnabled:
  service.log("count of mbos "+mboset.count())
service 变量中的以下函数使您能够检查是否启用了日志记录:
if service.isLoggingEnabled():
  service.log(“count of mbos “+mboset.count())

避免访问脚本缓存

从自动化脚本代码访问脚本缓存会导致循环依赖,并导致脚本缓存加载(即部分加载)时不稳定。 编写脚本时,请使用库脚本进行模块化脚本开发,从而避免从缓存中访问脚本。