Source:
<code>public void start() throws Exception { JsonObject config = new JsonObject().put("url", "jdbc:hsqldb:mem:test?shutdown=true") .put("driver_class", "org.hsqldb.jdbcDriver"); String sql = "CREATE TABLE colors (" + "id INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY, " + "name VARCHAR(255), " + "datetime TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL)"; JDBCClient client = JDBCClient.createShared(vertx, config); client .rxGetConnection() .flatMap(conn -> conn .rxSetAutoCommit(false) .flatMap(autoCommit -> conn.rxExecute(sql)) .flatMap(executed -> conn.rxUpdateWithParams("INSERT INTO colors (name) VALUES (?)", new JsonArray().add("BLACK"))) .flatMap(updateResult -> conn.rxUpdateWithParams("INSERT INTO colors (name) VALUES (?)", new JsonArray().add("WHITE"))) .flatMap(updateResult -> conn.rxUpdateWithParams("INSERT INTO colors (name) VALUES (?)", new JsonArray().add("PURPLE"))) .flatMap(updateResult -> conn.rxQuery("SELECT * FROM colors")) <START> .doOnSuccess(resultSet -> conn.rxCommit().subscribe()) <END> .doOnError(throwable -> conn.rxRollback().subscribe()) .doAfterTerminate(conn::close) ).subscribe(resultSet -> { System.out.println("Results : " + resultSet.getRows()); }, Throwable::printStackTrace); }</code><technical_language>In general, I recommend nesting subscribes this. nesting subscribes, error emitted commit/rollback propagated caller. commit/rollback happen asynchronously, creates a race condition code downstream execute commit/rollback completes. semantics change, rollback method called if commit call fails, if flatMap/map combo (and if doOnSuccess/doOnError combo worked thought did). I guess ok for example, I a good pattern, considered side-effects (no error propagation, stuff downstream run concurrently) ok them. This applies for RxJava 2 example</technical_language>

Target:
public void start() throws Exception { JsonObject config = new JsonObject().put("url", "jdbc:hsqldb:mem:test?shutdown=true") .put("driver_class", "org.hsqldb.jdbcDriver"); String sql = "CREATE TABLE colors (" + "id INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY, " + "name VARCHAR(255), " + "datetime TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL)"; JDBCClient client = JDBCClient.createShared(vertx, config); client .rxGetConnection() .flatMap(conn -> conn .rxSetAutoCommit(false) .flatMap(autoCommit -> conn.rxExecute(sql)) .flatMap(executed -> conn.rxUpdateWithParams("INSERT INTO colors (name) VALUES (?)", new JsonArray().add("BLACK"))) .flatMap(updateResult -> conn.rxUpdateWithParams("INSERT INTO colors (name) VALUES (?)", new JsonArray().add("WHITE"))) .flatMap(updateResult -> conn.rxUpdateWithParams("INSERT INTO colors (name) VALUES (?)", new JsonArray().add("PURPLE"))) .flatMap(updateResult -> conn.rxCommit().map(commit -> updateResult)) .onErrorResumeNext(ex -> conn.rxRollback() .onErrorResumeNext(ex2 -> Single.error(new CompositeException(ex, ex2))) .flatMap(ignore -> Single.error(ex)) ) .flatMap(updateResult -> conn.rxQuery("SELECT * FROM colors")) .doAfterTerminate(conn::close) ).subscribe(resultSet -> { System.out.println("Results : " + resultSet.getRows()); }, Throwable::printStackTrace); }