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 激活组可以在作业中保持活动状态。
我有一个 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 激活组可以在作业中保持活动状态。