IBM i RPG 程序在使用 JT400 连接池调用后引用了错误的库

IBM i RPG programs are referencing the wrong library after calling them using a JT400 connection pool

我有一个 Java 调用 CL 程序的应用程序,然后使用 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 的打开连接,许多不同的作业可能同时 运行ning,大多数来自同一个库,只有少数在不同的库中。 运行 相同的呼叫稍后会顺利通过。

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

例如以下 CL 调用:

CALL PGM(ADDPRGXX/TESTCL)

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

TESTRPG *INIT ADDPRGXX OPEN SOMEFILE CPF4131 Level check on file SOMEFILE in library ADDFILXS with member SOMEFILE.

&N Cause . . . . . : The RPG program TESTRPG in library ADDPRGXX received the message CPF4131 while doing an implicit OPEN to file SOMEFILE. See the job log for a complete description of message CPF4131. If the file has a device type of SPECIAL, there may be no message in the job log. &N Recovery . . . : Enter C to cancel, S to obtain a printout of system storage, D to obtain an RPG formatted printout of system storage, or F to obtain a full formatted printout of system storage. &N Possible choices for replying to message . . . . . . . . . . . . . . . : &B D -- Obtain RPG formatted printout of system storage. &B S -- Obtain printout of system storage. &B F -- Obtain full formatted printout of system storage. &B C -- Cancel.

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

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

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

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

我现在开始为每个库使用 2 个独立的池,这似乎很有效。 但更愿意找到根本原因并修复它。

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

The example SOMEFILE doesn't exist in ADDFILXS but only in ADDFILXX

但如果你得到

,情况就不同了

CPF4131 Level check on file SOMEFILE in library ADDFILXS with member SOMEFILE

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

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

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

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

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

  • 更改库列表并不“便宜”
  • 允许程序保持活动状态并打开数据路径。
  • ILE 激活组可以在作业中保持活动状态。