Java reactive applications for Db2 data servers

You can run Java applications against Db2 data servers by using the IBM® Db2 Java Reactive Driver.

Creating Java reactive applications that utilize the Project Reactor framework requires a driver that provides a non-blocking, asynchronous API to access a data server. The IBM Db2 Java Reactive Driver, which uses Reactive Relational Database Connectivity (R2DBC), provides that capability. The IBM Db2 Java Reactive Driver can access data on the following data servers:
  • Db2 data servers on Linux, UNIX, and Windows systems
  • Db2 for z/OS® data servers
The IBM Db2 Java Reactive Driver uses some third-party components. The following figure shows the relationship among the driver components and the third-party components.
Figure 1. IBM Db2 Java Reactive Driver architecture
Java Reactive Driver components are the R2DBC API, DRDA flows, and DRDA library. Third-party components are Project Reactor, Reactor Netty, and Netty.

For more details on the IBM Db2 Java Reactive Driver, see Java Reactive Driver.

The basic steps in creating a Java reactive application are:

  1. Create a connection configuration:
    DB2ConnectionConfiguration config = DB2ConnectionConfiguration.builder()
    				.database("database-name")
    				.host("host-name")
    				.port(port-number)
    				.username("username")
    				.password("password")
    				.conPoolSize(integer)
    				.stmtCacheSize(integer)
    				.build();
    

    The database, host, port, username, and password parameter values provide the information for connecting to the target data server.

    The conPoolSize value represents the maximum number of data server connections in the pool. The default value is 10.

    The stmtCacheSize value represents the maximum number of statements to be cached in a connection. The default value is 30.

    The API that is accessed by the IBM Db2 Java Reactive Driver uses a DB2ConnectionFactory object. That object, when instantiated, allows you to create a connection to a data server by calling the create method.

  2. Using the connection config file, create your connection factory:
    DB2ConnectionFactory factory = new DB2ConnectionFactory(config);
  3. Using the ConnectionFactory object that you defined in the previous step, create a connection pool:
    DB2ConnectionPool pool = new DB2ConnectionPool(factory);
  4. Obtain a connection from the connection pool. You can now run DDL statements asynchronously against the Db2 data server from your Java reactive application.

The following example shows the command syntax and output from obtaining a connection from a connection pool and running a DDL statement to create a DEMO table:

AtomicReference<DB2Connection> con = new AtomicReference<DB2Connection>();
		
	Mono<Void> mono = pool.getConnection()
			.doOnNext(c -> con.set(c))
			.flatMap(c -> c.executeUpdate(
					"CREATE TABLE DEMO (" +
						"ID INTEGER UNIQUE NOT NULL, " +
						"ACC_BAL DECIMAL(10,2) NOT NULL, " +
						"AS_OF TIMESTAMP NOT NULL" +
					")"
			))
			.doOnTerminate(() -> con.get().release());

The following example shows a DML statement for adding data into the newly created table, DEMO:
	Mono<DB2Result> mono = pool.getConnection()
		.doOnNext(c -> con.set(c))
		.flatMap(c -> c.createStatement("INSERT INTO DEMO (ID, ACC_BAL,
 					AS_OF) VALUES (?, ?, ?)")
				   		 .bind(1, id)
				   		 .bind(2, amount)
				   		 .bind(3, Timestamp.from(Instant.now()))
				   		 .execute())
		.doAfterTerminate(() -> con.get().release());
The following example shows the command syntax for closing connections in a connection pool:
// Close all the connections in the pool
Mono<Void> mono = pool.closeAll();