管理 Java 程序中的连接

重要的是能够创建,启动和结束与服务器的连接。 以下讨论说明了对管理与服务器的连接至关重要的概念,还提供了一些代码示例。

要连接到 IBM i 服务器,您的 Java™ 程序必须创建一个 AS400 对象。 对于每种 IBM i 服务器类型, AS400 对象最多包含一个套接字连接。 服务对应于服务器上的作业,是服务器上数据的接口。

注: 创建 Enterprise JavaBeans (EJB) 时,请遵循在连接期间不允许线程的 EJB 规范。 虽然关闭 IBM® Toolbox for Java 线程支持可能会降低应用程序的运行速度,但这是遵守 EJB 规范所必需的。

与每个服务器的每个连接在系统上都有自己的作业。 不同的服务器支持下列各项:

  • JDBC
  • 程序调用和命令调用
  • 集成文件系统
  • 打印
  • 数据队列
  • 记录级访问
注:
  • 如果应用程序不尝试同时执行需要网络打印服务器的两项操作,那么 print 类将对每个 AS400 对象使用一个套接字连接。
  • 如果需要, print 类会创建到网络打印服务器的其他套接字连接。 如果额外的对话未用于 5 分钟,那么这些对话将断开连接。

Java 程序可以控制与系统的连接数。 为了优化通信性能, Java 程序可以为同一服务器创建多个 AS400 对象,如图 1 所示。 这将创建到系统的多个套接字连接。

图 1: 为同一系统创建多个 AS400 对象和套接字连接的 Java 程序

为同一系统创建多个 AS400 对象和套接字连接的 Java 程序

要节省服务器资源,请仅创建一个 AS400 对象,如图 2 中所示。 此方法可减少连接数,这将减少服务器上使用的资源量。

图 2: 为同一系统创建单个 AS400 对象和套接字连接的 Java 程序

为同一系统创建单个 AS400 对象和套接字连接的 Java 程序

注: 虽然创建更多连接会增加服务器上使用的资源量,但创建更多连接可能有好处。 有更多的连接使您的 Java 程序能够并行处理事物,这可以提供更好的吞吐量 (每秒事务数) 并加快应用程序的速度。

您还可以选择使用连接池来管理连接,如图 3 所示。 此方法通过复用先前为用户建立的连接来减少连接所花费的时间。

图 3 :Java 程序获取从 AS400ConnectionPool 到服务器的连接

Java 程序获取从 AS400ConnectionPool 到服务器的连接

以下示例显示了如何创建和使用 AS400 对象:

示例 1: 在以下示例中,将创建两个 CommandCall 对象以将命令发送到同一服务器。 由于 CommandCall 对象使用相同的 AS400 对象,因此仅创建与服务器的一个连接。

     // Create an AS400 object.
     AS400 sys = new AS400("mySystem.myCompany.com");
 
     // Create two command call objects that use
     // the same AS400 object.
     CommandCall cmd1 = new CommandCall(sys,"myCommand1");
     CommandCall cmd2 = new CommandCall(sys,"myCommand2");
 
     // Run the commands.  A connection is made when the
     // first command is run.  Since they use the same
     // AS400 object the second command object will use
     // the connection established by the first command.
     cmd1.run();
     cmd2.run();

示例 2: 在以下示例中,将创建两个 CommandCall 对象以将命令发送到同一系统。 由于 CommandCall 对象使用不同的 AS400 对象,因此将创建与服务器的两个连接。

     // Create two AS400 objects to the same server.
     AS400 sys1 = new AS400("mySystem.myCompany.com");
     AS400 sys2 = new AS400("mySystem.myCompany.com");
 
     // Create two command call objects.  They use
     // different AS400 objects.
     CommandCall cmd1 = new CommandCall(sys1,"myCommand1");
     CommandCall cmd2 = new CommandCall(sys2,"myCommand2");
 
     // Run the commands.  A connection is made when the
     // first command is run.  Since the second command
     // object uses a different AS400 object, a second
     // connection is made when the second command is run.
     cmd1.run();
     cmd2.run();

示例 3: 在下面的示例中,使用同一个 CommandCall 对象创建了 IFSFileInputStream 对象。 由于 CommandCall 对象和 IFSFileInput 流对象在服务器上使用不同的服务,因此会创建两个连接。

     // Create an AS400 object.
     AS400 newConn1 = new AS400("mySystem.myCompany.com");
 
     // Create a command call object.
     CommandCall cmd = new CommandCall(newConn1,"myCommand1");
 
     // Create the file object.  Creating it causes the
     // AS400 object to connect to the file service.
     IFSFileInputStream file = new IFSFileInputStream(newConn1,"/myfile");
 
     // Run the command.  A connection is made to the
     // command service when the command is run.
     cmd.run();

示例 4: 在以下示例中, AS400ConnectionPool 用于获取 IBM i 连接。 此示例 (如上面的 示例 3 ) 未指定服务,因此在运行命令时将与命令服务建立连接。

     // Create an AS400ConnectionPool.
     AS400ConnectionPool testPool1 = new AS400ConnectionPool();

     // Create a connection.
     AS400 newConn1 = testPool1.getConnection("myAS400", "myUserID", "myPassword");

     // Create a command call object that uses the AS400 object.
     CommandCall cmd = new CommandCall(newConn1,"myCommand1");

     // Run the command.  A connection is made to the
     // command service when the command is run.
     cmd.run();

     // Return connection to pool.
     testPool1.returnConnectionToPool(newConn1);

示例 5: 以下示例使用 AS400ConnectionPool 在从池请求连接时连接到特定服务。 这将消除运行命令时连接到服务所需的时间 (请参阅上面的 示例 4 )。 如果将连接返回到池,那么下一个用于获取连接的调用可以返回相同的连接对象。 这意味着创建或使用时不需要额外的连接时间。

     // Create an AS400ConnectionPool.
     AS400ConnectionPool testPool1 = new AS400ConnectionPool();

     // Create a connection to the AS400.COMMAND service. (Use the service number constants 
     // defined in the AS400 class (FILE, PRINT, COMMAND, DATAQUEUE, and so on.))
     AS400 newConn1 = testPool1.getConnection("myAS400", "myUserID", "myPassword", AS400.COMMAND);

     // Create a command call object that uses the AS400 object.
     CommandCall cmd = new CommandCall(newConn1,"myCommand1");

     // Run the command.  A connection has already been made
     // to the command service.
     cmd.run();

     // Return connection to pool.
     testPool1.returnConnectionToPool(newConn1);

     // Get another connection to command service.  In this case, it will return the same 
     // connection as above, meaning no extra connection time will be needed either now or
     // when the command service is used.
     AS400 newConn2 = testPool1.getConnection("myAS400", "myUserID", "myPassword", AS400.COMMAND);

启动和结束连接

Java 程序可以控制何时启动和结束连接。 缺省情况下,当需要来自服务器的信息时,将启动连接。 您可以通过调用 AS400 对象上的 connectService() 方法来预先连接服务器,从而精确控制连接的时间。

使用 AS400ConnectionPool 可以创建预连接到服务的连接,而无需调用 connectService() 方法,如上文 例 5 所示。

以下示例显示了与系统连接和断开连接的 Java 程序。

示例 1: 此示例显示如何预连接到系统:

     // Create an AS400 object.
     AS400 system1 = new AS400("mySystem.myCompany.com");
 
     // Connect to the command service.  Do it now
     // instead of when data is first sent to the
     // command service.  This is optional since the
     // AS400 object will connect when necessary.
     system1.connectService(AS400.COMMAND);

示例 2: 启动连接后, Java 程序将负责断开连接,此操作由 AS400 对象隐式完成或由 Java 程序显式完成。 Java 程序通过调用 AS400 对象上的 disconnectService() 方法来断开连接。 要提高性能, Java 程序必须仅在程序完成服务时断开连接。 如果 Java 程序在完成服务之前断开连接,那么当需要来自服务的数据时, AS400 对象将重新连接 (如果可以重新连接)。

图 4 显示了如何断开第一个集成文件系统对象连接的连接仅结束 AS400 对象连接的单个实例,而不是所有集成文件系统对象连接。

图 4: 将其自己的服务用于 AS400 对象实例的单个对象已断开连接

将其自己的服务用于 AS400 对象实例的单个对象已断开连接

此示例显示 Java 程序如何断开连接:

     // Create an AS400 object.
     AS400 system1 = new AS400("mySystem.myCompany.com");
 
     // ... use command call to send several commands
     // to the server.  Since connectService() was not
     // called, the AS400 object automatically
     // connects when the first command is run.
 
     // All done sending commands so disconnect the
     // connection.
     system1.disconnectService(AS400.COMMAND);

示例 3: 使用同一服务并共享同一 AS400 对象的多个对象共享一个连接。 断开连接将结束对 AS400 对象的每个实例使用相同服务的所有对象的连接,如图 5 所示。

图 5: 对 AS400 对象的实例使用同一服务的所有对象都已断开连接

对 AS400 对象的实例使用同一服务的所有对象都已断开连接

例如,两个 CommandCall 对象使用相同的 AS400 对象。 调用 disconnectService() 时,两个 CommandCall 对象的连接都将结束。 当调用第二个 CommandCall 对象的 run () 方法时, AS400 对象必须重新连接到服务:

     // Create an AS400 object.
     AS400 sys = new AS400("mySystem.myCompany.com");
 
     // Create two command call objects.
     CommandCall cmd1 = new CommandCall(sys,"myCommand1");
     CommandCall cmd2 = new CommandCall(sys,"myCommand2");
 
     // Run the first command
     cmd1.run();
 
     // Disconnect from the command service.
     sys.disconnectService(AS400.COMMAND);
 
     // Run the second command.  The AS400 object
     // must reconnect to the server.
     cmd2.run();
 
     // Disconnect from the command service.  This
     // is the correct place to disconnect.
     sys.disconnectService(AS400.COMMAND);

示例 4: 并非所有 IBM Toolbox for Java 类都会自动重新连接。 集成文件系统 类中的某些方法调用不会重新连接,因为该文件可能已更改。 当该文件已断开连接时,其他一些进程可能已删除该文件或更改其内容。 在以下示例中,两个文件对象使用相同的 AS400 对象。 调用 disconnectService() 时,两个文件对象的连接都将结束。 第二个 IFSFileInputStream 对象的 read() 失败,因为它不再与服务器有连接。

     // Create an AS400 object.
     AS400 sys = new AS400("mySystem.myCompany.com");
 
     // Create two file objects.  A connection to the
     // server is created when the first object is
     // created.  The second object uses the connection
     // created by the first object.
     IFSFileInputStream file1 = new IFSFileInputStream(sys,"/file1");
     IFSFileInputStream file2 = new IFSFileInputStream(sys,"/file2");
 
     // Read from the first file, then close it.
     int i1 = file1.read();
     file1.close();
 
     // Disconnect from the file service.
     sys.disconnectService(AS400.FILE);
 
     // Attempt to read from the second file.  This
     // fails because the connection to the file service
     // no longer exists.  The program must either
     // disconnect later or have the second file use a
     // different AS400 object (which causes it to
     // have its own connection).
     int i2 = file2.read();
 
     // Close the second file.
     file2.close();
 
     // Disconnect from the file service.  This
     // is the correct place to disconnect.
     sys.disconnectService(AS400.FILE);