1

我有一个调用 CL 程序的 Java 应用程序,然后使用 JT400 库在 IBM i 系统上运行多个 RPG 程序。

起初,我每次都打开一个新连接,就像这样,完成后关闭它:

new AS400(hostname, username, password);

但是由于连接数量的增加,我最近开始使用连接池:

@Bean
public AS400ConnectionPool as400ConnectionPool() {
    String hostname = env.getProperty("AS400Hostname");
    String username = env.getProperty("AS400Username");
    String password = env.getProperty("AS400Password");

    AS400ConnectionPool as400ConnectionPool = new AS400ConnectionPool();
    as400ConnectionPool.setMaxConnections(128);

    try {
        // Preconnect 5 connections to the AS400.COMMAND service.
        as400ConnectionPool.fill(hostname, username, password, AS400.COMMAND, 5);
    } catch (ConnectionPoolException e) {
        log.error(e.getMessage());
        e.printStackTrace();
    }
    return as400ConnectionPool;
}

现在,每个连接在使用后都会返回到池中,而不是被关闭。

不幸的是,我们开始看到之前运行完美的相同作业,有时会在 IBM i 上进入 MSGW 状态。(消息等待)

在分析作业日志时,我注意到最后出现以下类型的错误:

CPF4131 在文件打开期间出现

大约在同一时间从 2 个不同的库运行作业时似乎正在发生这种情况。该程序通常同时有大约 10 个与 IBM i 的开放连接,并且可能同时运行许多不同的作业,大多数来自同一个库,只有少数在不同的库中。稍后运行相同的呼叫然后毫无问题地进行。

我在其中运行程序调用的库似乎正在寻找另一个库中的文件,该文件未在该程序中引用。

例如以下 CL 调用:

呼叫 PGM(ADDPRGXX/TESTCL)

最终会在后续的 RPG 调用中导致类似这样的错误:

TESTRPG *INIT ADDPRGXX OPEN SOMEFILE CPF4131 使用成员 SOMEFILE 对库 ADDFILXS 中的文件 SOMEFILE 进行级别检查。

&N 原因。. . . . : 库 ADDPRGXX 中的 RPG 程序 TESTRPG 在对文件 SOMEFILE 执行隐式打开时收到消息 CPF4131。有关消息 CPF4131 的完整描述,请参阅作业日志。如果文件的设备类型为 SPECIAL,则作业日志中可能没有消息。&N 恢复。. . :输入C取消,输入S获取系统存储打印输出,D获取系统存储RPG格式打印输出,或输入F获取系统存储全格式打印输出。&N 回复消息的可能选择。. . . . . . . . . . . . . . : &B D -- 获取系统存储的 RPG 格式打印输出。&B S -- 获取系统存储的打印输出。&B F -- 获取系统存储的完整格式打印输出。&B C -- 取消。

示例 SOMEFILE 在 ADDFILXS 中不存在,但仅在 ADDFILXX 中,在程序调用中从不引用 ADDFILXS。

CL 程序首先添加必要的库,然后调用 RPG,例如:

ADDLIBLE LIB(ADDPRGXX)
MONMSG MSGID (CPF0000)
ADDLIBLE LIB(ADDFILXX)
MONMSG MSGID (CPF0000)
CALL TESTRPG

在随后的 RPG 调用中是否需要对库进行一些引用?或者我应该对连接池做其他事情来防止这种情况发生吗?

我现在已经开始为每个库使用 2 个单独的池,这似乎正在工作。但更愿意找到根本原因并解决它。

4

1 回答 1

3

我怀疑发生的事情比你知道的要多(或者你过度简化了你的例子)

示例 SOMEFILE 在 ADDFILXS 中不存在,而仅在 ADDFILXX 中

但如果你得到

CPF4131 使用成员 SOMEFILE 对库 ADDFILXS 中的文件 SOMEFILE 进行级别检查

如果 SOMEFILE 实际上不存在,那将是一条不同的消息。

无论如何,有很多陷阱试图通过在工作生命周期的中间更改库列表来改变“环境”。由于您已经开始使用连接池,连接在 IBM i 端保持打开状态,因此操作系统不会在使用之间重置 QZDASOINIT(或相关作业)。

您没有提及您是否正在使用 ILE 或 OPM 程序。但是每个人都有自己的一系列问题,如果将它们混合在一起,情况会变得更糟;OPM CL 调用 ILE RPG。

最好的解决方案是您想出的那个,为不同的环境使用单独的池。

它不仅更安全,而且性能也会更好。

  • 更改图书馆列表并不“便宜”
  • 允许程序保持活动状态并打开数据路径保持打开状态。
  • ILE 激活组可以在作业中保持活动状态。
于 2020-09-10T21:43:27.757 回答