SlideShare a Scribd company logo
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
JDBC Next: A New
Asynchronous API for
Connecting to a Database
CON1491
Douglas Surber
JDBC Architect
Oracle Database Server Technologies
October 3, 2017
3
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Safe Harbor Statement
The following is intended to outline our general product direction. It is intended for
information purposes only, and may not be incorporated into any contract. It is not a
commitment to deliver any material, code, or functionality, and should not be relied upon
in making purchasing decisions. The development, release, and timing of any features or
functionality described for Oracle’s products remains at the sole discretion of Oracle.
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
Overview1
2
3
4
Confidential – Oracle Internal/Restricted/Highly Restricted 5
Code
Wrap-up
Q&A
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Overview
6
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Asynchronous Database Access
• Java standard database access API that never blocks user threads
• Developed by the JDBC Expert Group with community input
• Targeted for a near future release, Java 10 or equivalent
• Asynchronous apps have better throughput
– Fewer threads means less thread scheduling, less thread contention
– Database access is slow so blocked threads leave resources idle for a long time
– Simultaneous access to multiple databases, e.g. map/reduce, sharded databases
– Fire and forget, e.g. DMS, stored procedures
7
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Goals
• No user thread blocks ever
– Minimize the number of threads used for database access
• Alternate API for database access
– Not an extension of the standard JDBC API
– Not a replacement for the standard JDBC API
• Target high throughput apps
– Not a completely general purpose database access API
– The initial version will have a limited feature set
• Build on the Java SE class library
8
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Design Choices
• Minimal or no reference to java.sql
• Rigorous use of types
• Builder pattern
• Fluent API
• Immutable after initialization
• One way to do something is enough
• Avoid SQL processing
• Avoid callback hell
9
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
What About … ?
• Streams
– Java streams are inherently synchronous
• ReactiveStreams
– Not integrated into the Java SE class library
• NodeJS
• ADBCJ
There are already multiple asynchronous/non-blocking database access APIs
10
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Code
11
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public void trivialInsert(DataSource ds) {
String sql = "insert into tab values (:id, :name, :answer)";
try (Connection conn = ds.getConnection()) {
conn.countOperation(sql)
.set("id", 1, JdbcType.NUMERIC)
.set("name", "Deep Thought", JdbcType.VARCHAR)
.set("answer", 42, JdbcType.NUMERIC)
.submit();
}
}
Trivial Insert
12
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
All SQL is Vendor Specific
• No escape sequences
• No specified parameter markers
• Non vendor specific syntax requires processing by the driver
– Adds overhead
– Increases code complexity
– Minimal benefit as most apps are tied to a specific database regardless
Note: Code examples use parameter markers from a variety of databases including DB2
(:foo), MySQL (?), Oracle Database(:foo), PostgresSQL($1), and SQL Server (@foo).
13
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public void trivialSelect(DataSource ds, List<Integer> result) {
String sql = "select id, name, answer " +
"from tab where answer = $1";
try (Connection conn = ds.getConnection()) {
conn.<List<Integer>>rowOperation(sql)
.set("1", 42, JdbcType.NUMERIC)
.rowAggregator( (ignore, row) -> {
result.add(row.get("id", Integer.class));
return null;
} )
.submit();
}
}
Trivial Select
14
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Execution Model
• Operations consist of
– SQL or other database operation
– Parameter assignments
– Result handling
– Submission and CompletableFuture
• User thread creates and submits Operations
– Creating and submitting never blocks; user thread never blocks
• Implementation executes those Operations asynchronously
– Performs round trip(s) to the database
– Executes result handling
– Completes CompletableFutures
15
Everything is an Operation
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public DataSource getDataSource(String url, String user, String pass) {
return DataSourceFactory.forName("Oracle Database")
.builder()
.url("oracle:database:@//javaone.oracle.com:5521/javaone")
.username("scott")
.password("tiger")
.connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION,
TransactionIsolation.SERIALIZABLE)
.build();
}
Getting a DataSource
16
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
in interface DataSource:
public default Connection getConnection() {
return builder().build().connect();
}
in interface Connection:
public default Connection connect() {
holdForMoreMembers();
submit();
connectOperation().submit();
return this;
}
Getting a Connection
17
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public Future<Integer> selectIdForAnswer(DataSource ds, int answer) {
String sql = "select id, name, answer from tab " +
"where answer = @target";
try (Connection conn = ds.getConnection()) {
return conn.<List<Integer>>rowOperation(sql)
.set("target", 42, JdbcType.NUMERIC)
.initialValue( () -> new ArrayList<>() )
.rowAggregator( (list, row) -> {
list.add(row.get("id", Integer.class));
return list;
} )
.submit()
.toCompletableFuture()
.thenApply( l -> l.get(0) );
}
}
Basic SELECT
18
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public static class Item {
protected int id;
protected String name;
protected int answer;
@SqlColumns( { “ID”, “USER”, “RESPONSE” } )
public Item(int id, String name, int answer) {
this.id = id;
this.name = name;
this.answer = answer;
}
(cont.)
POJOs
19
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
@SqlParameter(marker=”id”, sqlType="NUMERIC")
public int getId() {
return id;
}
@SqlParameter(marker=”name”, sqlType="VARCHAR")
public String getName() {
return name;
}
@SqlParameter(marker=”answer”, sqlType="NUMERIC")
public int getAnswer() {
return answer;
}
}
POJOs (cont.)
20
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public void insertListIndependent(List<Item> list, DataSource ds) {
String sql = "insert into tab values " +
"(:elem_id, :elem_name, :elem_answer)";
try (Connection conn = ds.getConnection()) {
BatchCountOperation batch = conn.batchCountOperation(sql);
list.forEach( (elem) -> {
batch.countOperation()
.set("elem_", elem)
.submit();
});
batch.submit();
}
}
Batch Insert
21
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
OperationGroup
• OperationGroup has its own result handling and CompletableFuture
• Members submitted to group. OperationGroup is submitted as a unit
• Order of execution
– Sequential in order submitted
– Parallel, any order
• Error response
– Dependent: remaining group members skipped
– Independent: remaining group members unaffected
• Conditional or unconditional
• Connection is an OperationGroup
– Sequential, dependent, unconditional by default
22
Operations can be grouped
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public void insertListHold(List<Item> list, DataSource ds) {
String sql = "insert into tab " +
"values (@elem_id, @elem_name, @elem_answer)";
try (Connection conn = ds.getConnection()) {
OperationGroup group = conn.operationGroup()
.holdForMoreMembers()
.independent();
group.submit();
(cont.)
Independent INSERT
23
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
for (Item elem : list) {
group.countOperation(sql)
.set("elem_", elem)
.submit()
.toCompletableFuture()
.exceptionally( t -> {
System.out.println(elem.getId());
return null;
});
}
group.releaseProhibitingMoreMembers();
}
}
Independent Insert (cont.)
24
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
in interface Connection
public default void close() {
closeOperation().submit();
releaseProhibitingMoreMembers();
}
Note: A CloseOperation is never skipped.
Close
25
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
in interface Connection
public Connection activate();
public Connection deactivate();
public registerLifecycleListener(LifecycleListener listener);
Connection Pooling
26
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public DataSource getDataSource(String url, String user, String pass) {
return DataSourceFactory.forName("Oracle Database")
.builder()
.url("oracle:database:@//javaone.oracle.com:5521/javaone")
.username("scott")
.password("tiger")
.connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION,
TransactionIsolation.SERIALIZABLE)
.connectionProperty(NLS_LANGUAGE, “French”)
.build();
}
ConnectionProperties
27
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public static class NlsLanguageProperty implements ConnectionProperty {
public static final ConnectionProperty NLS_LANGUAGE
= new NlsLanguageProperty();
private NlsLanguageProperty() {}
public String name() { return “NLS_LANGUAGE”; }
public Class range() { return String.class; }
public String defaultValue() { return “American”; }
public boolean isSensitive() { return false; }
public Operation configureOperation(OperationGroup group, Object value) {
String sql = “ALTER SESSION SET NLS_LANGUAGE TO “ + value;
return group.operation(sql);
}
ConnectionProperty
28
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
@SqlArray(elementSqlTypeName=”STUDENT”)
public class Roster extends LinkedList<Student> {
public Roster() {};
}
@SqlStruct(sqlTypeName=”STUDENT”, fields={
@Field(sqlFieldName=”NAME”, sqlTypeName=”VARCHAR(100)”, javaFieldName=”name”),
@Field(sqlFieldName=”EMAIL”, sqlTypeName=”VARCHAR(100)”,
javaFieldName=”email”)})
public class Student {
String name;
String email;
public void setName(String n) {name = n;}
public void setEmail(String e) {email = e;}
public String getName() {return name;}
public String getEmail() {return email;}
}
ARRAYs and STRUCTs
29
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public void transfer(Connection conn,
double amount, int fromAccount, int toAccount) {
String sql = “update account set balance=balance+@amount where id = @account”;
conn.countOperation(sql)
.set(“amount”, -amount, JdbcType.DECIMAL)
.set(“account”, fromAccount, JdbcType.INTEGER)
.submit();
conn.countOperation(sql)
.set(“amount”, amount, JdbcType.DECIMAL)
.set(“account”, toAccount, JdbcType.INTEGER)
.submit();
conn.commit();
}
Transactions
30
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public void transfer(Connection conn,
double amount, int fromAccount, int toAccount) {
String sql = “update account set balance=balance+@amount where id = @account”;
final Transaction tran = conn.getTransaction();
conn.countOperation(sql)
.set(“amount”, -amount, JdbcType.DECIMAL)
.set(“account”, fromAccount, JdbcType.INTEGER)
.onError( e -> tran.setRollbackOnly() )
.submit();
conn.countOperation(sql)
.set(“amount”, amount, JdbcType.DECIMAL)
.set(“account”, toAccount, JdbcType.INTEGER)
.onError( e -> tran.setRollbackOnly() )
.submit();
conn.commit();
}
Transactions (cont.)
31
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public void paycheck(Connection conn, Employee emp) {
String sql = “call generate_paycheck(?, ?)”;
CompletableFuture<CheckDetail> details = conn.<CheckDetail>outOperation(sql)
.set(“1”, emp, JdbcType.STRUCT)
.outParameter(“2”, JdbcType.STRUCT)
.resultProcessor( m -> m.get(“2”, CheckDetail.class) )
.submit()
.toCompletableFuture();
conn.localOperation()
.onExecution( () -> { printPaycheck(details); return null; } )
.submit()
.toCompletableFuture()
.thenRun( () -> reportPrintSuccess(details) );
.exceptionally( t -> {reportPrintFailure(details); return null;} );
}
Local Operations
32
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public void deposit(Connection conn, int accountId, double amount) {
String selectSql = “select balance from account where id = $1”;
CompletableFuture<Double> newBalanceF = conn <Double>rowOperation(selectSql)
.set(“1”, accountId, JdbcType.INTEGER)
.rowAggregator( (p, row) -> row.get(“balance”, Double.class) )
.submit()
.toCompletableFuture()
.thenApply( b -> b + amount );
String updateSql = “update account set balance=$2 where id = $1”;
conn.countOperation(updateSql)
.set(“1”, accountId, JdbcType.INTEGER)
.set(“2”, newBalanceF, JdbcType.DOUBLE)
.submit();
}
Future Parameters
33
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Wrap-up
34
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Status
• Everything is subject to change
• Prototype Oracle Database driver implements much of the API
– Uses nio Selector so non-blocking all the way down
• Developed by the JDBC Expert Group through the Java Community Process
• Targeted for a near future release, Java 10 or equivalent
• The API is available for download from OpenJDK at
http://oracle.com/goto/java-async-db
• Send feedback to jdbc-spec-discuss@openjdk.java.net
35
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Q&A
36
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | 37
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test;
import java.sql2.BatchCountOperation;
import java.sql2.Connection;
import java.sql2.ConnectionProperty;
import java.sql2.DataSource;
import java.sql2.DataSourceFactory;
import java.sql2.JdbcConnectionProperty;
import java.sql2.JdbcConnectionProperty.TransactionIsolation;
import java.sql2.JdbcType;
import java.sql2.Operation;
import java.sql2.OperationGroup;
import java.sql2.SqlArray;
import java.sql2.SqlColumns;
import java.sql2.SqlParameter;
import java.sql2.SqlStruct;
import java.sql2.SqlStruct.Field;
import java.sql2.Transaction;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Consumer;
/**
*
* Code from JavaOne 2017 slides: CON-1491
* JDBC Next: A New Asynchronous API for Connecting to a Database
*
*/
public class JavaOne {
public void trivialInsert(DataSource ds) {
String sql = "insert into tab values (:id, :name, :answer)";
try (Connection conn = ds.getConnection()) {
conn.countOperation(sql)
.set("id", 1, JdbcType.NUMERIC)
.set("name", "Deep Thought", JdbcType.VARCHAR)
.set("answer", 42, JdbcType.NUMERIC)
.submit();
}
}
public void trivialSelect(DataSource ds, List<Integer> result) {
String sql = "select id, name, answer "
+ "from tab where answer = $1";
try (Connection conn = ds.getConnection()) {
conn.<List<Integer>>rowOperation(sql)
.set("1", 42, JdbcType.NUMERIC)
.rowAggregator((ignore, row) -> {
result.add(row.get("id", Integer.class));
return null;
})
.submit();
}
}
public DataSource getDataSource(String url, String user, String pass) {
return DataSourceFactory.forName("Oracle Database")
.builder()
.url("oracle:database:@//javaone.oracle.com:5521/javaone")
.username("scott")
.password("tiger")
.connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION,
TransactionIsolation.SERIALIZABLE)
.build();
}
public Future<Integer> selectIdForAnswer(DataSource ds, int answer) {
String sql = "select id, name, answer from tab "
+ "where answer = @target";
try (Connection conn = ds.getConnection()) {
return conn.<List<Integer>>rowOperation(sql)
.set("target", 42, JdbcType.NUMERIC)
.initialValue(() -> new ArrayList<>())
.rowAggregator((list, row) -> {
list.add(row.get("id", Integer.class));
return list;
})
.submit()
.toCompletableFuture()
.thenApply(l -> l.get(0));
}
}
public void insertListIndependent(List<Item> list, DataSource ds) {
String sql = "insert into tab values "
+ "(:elem_id, :elem_name, :elem_answer)";
try (Connection conn = ds.getConnection()) {
BatchCountOperation batch = conn.batchCountOperation(sql);
list.forEach((elem) -> {
batch.countOperation()
.set("elem_", elem)
.submit();
});
batch.submit();
}
}
public void insertListHold(List<Item> list, DataSource ds) {
String sql = "insert into tab "
+ "values (@elem_id, @elem_name, @elem_answer)";
try (Connection conn = ds.getConnection()) {
OperationGroup group = conn.operationGroup()
.holdForMoreMembers()
.independent();
group.submit();
for (Item elem : list) {
group.countOperation(sql)
.set("elem_", elem)
.submit()
.toCompletableFuture()
.exceptionally(t -> {
System.out.println(elem.getId());
return null;
});
}
group.releaseProhibitingMoreMembers();
}
}
public DataSource getDataSource_2(String url, String user, String pass) {
return DataSourceFactory.forName("Oracle Database")
.builder()
.url("oracle:database:@//javaone.oracle.com:5521/javaone")
.username("scott")
.password("tiger")
.connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION,
TransactionIsolation.SERIALIZABLE)
.connectionProperty(NlsLanguageProperty.NLS_LANGUAGE, "French")
.build();
}
public void transfer(Connection conn,
double amount, int fromAccount, int toAccount) {
String sql = "update account set balance=balance+@amount where id =
@account";
conn.countOperation(sql)
.set("amount", -amount, JdbcType.DECIMAL)
.set("account", fromAccount, JdbcType.INTEGER)
.submit();
conn.countOperation(sql)
.set("amount", amount, JdbcType.DECIMAL)
.set("account", toAccount, JdbcType.INTEGER)
.submit();
conn.commit();
}
public void transfer_2(Connection conn,
double amount, int fromAccount, int toAccount) {
String sql = "update account set balance=balance+@amount where id =
@account";
final Transaction tran = conn.getTransaction();
conn.countOperation(sql)
.set("amount", -amount, JdbcType.DECIMAL)
.set("account", fromAccount, JdbcType.INTEGER)
.onError(e -> tran.setRollbackOnly())
.submit();
conn.countOperation(sql)
.set("amount", amount, JdbcType.DECIMAL)
.set("account", toAccount, JdbcType.INTEGER)
.onError(e -> tran.setRollbackOnly())
.submit();
conn.commit();
}
public void paycheck(Connection conn, Employee emp) {
String sql = "call generate_paycheck(?, ?)";
CompletableFuture<CheckDetail> details =
conn.<CheckDetail>outOperation(sql)
.set("1", emp, JdbcType.STRUCT)
.outParameter("2", JdbcType.STRUCT)
.resultProcessor(m -> m.get("2", CheckDetail.class))
.submit()
.toCompletableFuture();
conn.localOperation()
.onExecution(() -> {
printPaycheck(details);
return null;
})
.submit()
.toCompletableFuture()
.thenRun(() -> reportPrintSuccess(details))
.exceptionally(t -> {
reportPrintFailure(details);
return null;
});
}
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
public void deposit(Connection conn, int accountId, double amount) {
String selectSql = "select balance from account where id = $1";
CompletableFuture<Double> newBalanceF =
conn.<Double>rowOperation(selectSql)
.set("1", accountId, JdbcType.INTEGER)
.rowAggregator((p, row) -> row.get("balance", Double.class))
.submit()
.toCompletableFuture()
.thenApply(b -> b + amount);
String updateSql = "update account set balance=$2 where id = $1";
conn.countOperation(updateSql)
.set("1", accountId, JdbcType.INTEGER)
.set("2", newBalanceF, JdbcType.DOUBLE)
.submit();
}
public static class Item {
protected int id;
protected String name;
protected int answer;
@SqlColumns({"ID", "USER", "RESPONSE"})
public Item(int id, String name, int answer) {
this.id = id;
this.name = name;
this.answer = answer;
}
@SqlParameter(marker = "id", sqlType = "NUMERIC")
public int getId() {
return id;
}
@SqlParameter(marker = "name", sqlType = "VARCHAR")
public String getName() {
return name;
}
@SqlParameter(marker = "answer", sqlType = "NUMERIC")
public int getAnswer() {
return answer;
}
}
public static class NlsLanguageProperty implements ConnectionProperty {
public static final ConnectionProperty NLS_LANGUAGE
= new NlsLanguageProperty();
private NlsLanguageProperty() {
}
@Override
public String name() {
return "NLS_LANGUAGE";
}
@Override
public Class range() {
return String.class;
}
@Override
public String defaultValue() {
return "American";
}
@Override
public boolean isSensitive() {
return false;
}
@Override
public Operation configureOperation(OperationGroup group, Object value) {
String sql = "ALTER SESSION SET NLS_LANGUAGE TO " + value;
return group.operation(sql);
}
}
@SqlArray(elementSqlTypeName = "STUDENT")
public static class Roster extends LinkedList<Student> {
public Roster() {
}
}
@SqlStruct(sqlTypeName = "STUDENT", fields = {
@Field(sqlFieldName = "NAME", sqlTypeName = "VARCHAR(100)", javaFieldName = "name"),
@Field(sqlFieldName = "EMAIL", sqlTypeName = "VARCHAR(100)", javaFieldName = "email")})
public class Student {
String name;
String email;
public void setName(String n) {
name = n;
}
public void setEmail(String e) {
email = e;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
}
public class Employee {
}
public class CheckDetail {
}
private void printPaycheck(Future<CheckDetail> checkF) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of
generated methods, choose Tools | Templates.
}
private Consumer<? super Object> reportPrintSuccess(Future<CheckDetail> checkF) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of
generated methods, choose Tools | Templates.
}
private CompletableFuture<Void> reportPrintFailure(Future<CheckDetail> checkF) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of
generated methods, choose Tools | Templates.
}
}

More Related Content

What's hot

How many ways to monitor oracle golden gate - OOW14
How many ways to monitor oracle golden gate - OOW14How many ways to monitor oracle golden gate - OOW14
How many ways to monitor oracle golden gate - OOW14
Bobby Curtis
 
Enable GoldenGate Monitoring with OEM 12c/JAgent
Enable GoldenGate Monitoring with OEM 12c/JAgentEnable GoldenGate Monitoring with OEM 12c/JAgent
Enable GoldenGate Monitoring with OEM 12c/JAgent
Bobby Curtis
 
How easy (or hard) it is to monitor your graph ql service performance
How easy (or hard) it is to monitor your graph ql service performanceHow easy (or hard) it is to monitor your graph ql service performance
How easy (or hard) it is to monitor your graph ql service performance
Red Hat
 
R2DBC JEEConf 2019 by Igor Lozynskyi
R2DBC JEEConf 2019 by Igor LozynskyiR2DBC JEEConf 2019 by Igor Lozynskyi
R2DBC JEEConf 2019 by Igor Lozynskyi
Igor Lozynskyi
 
How and why to upgrade to java 16 or 17
How and why to upgrade to java 16 or 17How and why to upgrade to java 16 or 17
How and why to upgrade to java 16 or 17
Johan Janssen
 
Extreme replication at IOUG Collaborate 15
Extreme replication at IOUG Collaborate 15Extreme replication at IOUG Collaborate 15
Extreme replication at IOUG Collaborate 15
Bobby Curtis
 
Oracle GoldenGate and Baseball - 5 Keys for Moving to the Cloud
Oracle GoldenGate and Baseball - 5 Keys for Moving to the CloudOracle GoldenGate and Baseball - 5 Keys for Moving to the Cloud
Oracle GoldenGate and Baseball - 5 Keys for Moving to the Cloud
Bobby Curtis
 
Exachk and oem12c
Exachk and oem12cExachk and oem12c
Exachk and oem12c
Bobby Curtis
 
Oracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API ExamplesOracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API Examples
Bobby Curtis
 
MV2ADB - Move to Oracle Autonomous Database in One-click
MV2ADB - Move to Oracle Autonomous Database in One-clickMV2ADB - Move to Oracle Autonomous Database in One-click
MV2ADB - Move to Oracle Autonomous Database in One-click
Ruggero Citton
 
Continuous DB Changes Delivery With Liquibase
Continuous DB Changes Delivery With LiquibaseContinuous DB Changes Delivery With Liquibase
Continuous DB Changes Delivery With Liquibase
Aidas Dragūnas
 
Oracle GoldenGate on Docker
Oracle GoldenGate on DockerOracle GoldenGate on Docker
Oracle GoldenGate on Docker
Bobby Curtis
 
Terraform & Oracle Cloud Infrastructure
Terraform & Oracle Cloud InfrastructureTerraform & Oracle Cloud Infrastructure
Terraform & Oracle Cloud Infrastructure
Bobby Curtis
 
R2DBC Reactive Relational Database Connectivity
R2DBC Reactive Relational Database ConnectivityR2DBC Reactive Relational Database Connectivity
R2DBC Reactive Relational Database Connectivity
Maarten Smeets
 
Migrating to Spark 2.0 - Part 2
Migrating to Spark 2.0 - Part 2Migrating to Spark 2.0 - Part 2
Migrating to Spark 2.0 - Part 2
datamantra
 
Database Migrations with Gradle and Liquibase
Database Migrations with Gradle and LiquibaseDatabase Migrations with Gradle and Liquibase
Database Migrations with Gradle and Liquibase
Dan Stine
 
12 Factor App: Best Practices for JVM Deployment
12 Factor App: Best Practices for JVM Deployment12 Factor App: Best Practices for JVM Deployment
12 Factor App: Best Practices for JVM Deployment
Joe Kutner
 
Oem12c patching -OOW13
Oem12c patching -OOW13Oem12c patching -OOW13
Oem12c patching -OOW13Bobby Curtis
 
Reactors.io
Reactors.ioReactors.io
Reactors.io
Knoldus Inc.
 
Extreme Replication - RMOUG Presentation
Extreme Replication - RMOUG PresentationExtreme Replication - RMOUG Presentation
Extreme Replication - RMOUG Presentation
Bobby Curtis
 

What's hot (20)

How many ways to monitor oracle golden gate - OOW14
How many ways to monitor oracle golden gate - OOW14How many ways to monitor oracle golden gate - OOW14
How many ways to monitor oracle golden gate - OOW14
 
Enable GoldenGate Monitoring with OEM 12c/JAgent
Enable GoldenGate Monitoring with OEM 12c/JAgentEnable GoldenGate Monitoring with OEM 12c/JAgent
Enable GoldenGate Monitoring with OEM 12c/JAgent
 
How easy (or hard) it is to monitor your graph ql service performance
How easy (or hard) it is to monitor your graph ql service performanceHow easy (or hard) it is to monitor your graph ql service performance
How easy (or hard) it is to monitor your graph ql service performance
 
R2DBC JEEConf 2019 by Igor Lozynskyi
R2DBC JEEConf 2019 by Igor LozynskyiR2DBC JEEConf 2019 by Igor Lozynskyi
R2DBC JEEConf 2019 by Igor Lozynskyi
 
How and why to upgrade to java 16 or 17
How and why to upgrade to java 16 or 17How and why to upgrade to java 16 or 17
How and why to upgrade to java 16 or 17
 
Extreme replication at IOUG Collaborate 15
Extreme replication at IOUG Collaborate 15Extreme replication at IOUG Collaborate 15
Extreme replication at IOUG Collaborate 15
 
Oracle GoldenGate and Baseball - 5 Keys for Moving to the Cloud
Oracle GoldenGate and Baseball - 5 Keys for Moving to the CloudOracle GoldenGate and Baseball - 5 Keys for Moving to the Cloud
Oracle GoldenGate and Baseball - 5 Keys for Moving to the Cloud
 
Exachk and oem12c
Exachk and oem12cExachk and oem12c
Exachk and oem12c
 
Oracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API ExamplesOracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API Examples
 
MV2ADB - Move to Oracle Autonomous Database in One-click
MV2ADB - Move to Oracle Autonomous Database in One-clickMV2ADB - Move to Oracle Autonomous Database in One-click
MV2ADB - Move to Oracle Autonomous Database in One-click
 
Continuous DB Changes Delivery With Liquibase
Continuous DB Changes Delivery With LiquibaseContinuous DB Changes Delivery With Liquibase
Continuous DB Changes Delivery With Liquibase
 
Oracle GoldenGate on Docker
Oracle GoldenGate on DockerOracle GoldenGate on Docker
Oracle GoldenGate on Docker
 
Terraform & Oracle Cloud Infrastructure
Terraform & Oracle Cloud InfrastructureTerraform & Oracle Cloud Infrastructure
Terraform & Oracle Cloud Infrastructure
 
R2DBC Reactive Relational Database Connectivity
R2DBC Reactive Relational Database ConnectivityR2DBC Reactive Relational Database Connectivity
R2DBC Reactive Relational Database Connectivity
 
Migrating to Spark 2.0 - Part 2
Migrating to Spark 2.0 - Part 2Migrating to Spark 2.0 - Part 2
Migrating to Spark 2.0 - Part 2
 
Database Migrations with Gradle and Liquibase
Database Migrations with Gradle and LiquibaseDatabase Migrations with Gradle and Liquibase
Database Migrations with Gradle and Liquibase
 
12 Factor App: Best Practices for JVM Deployment
12 Factor App: Best Practices for JVM Deployment12 Factor App: Best Practices for JVM Deployment
12 Factor App: Best Practices for JVM Deployment
 
Oem12c patching -OOW13
Oem12c patching -OOW13Oem12c patching -OOW13
Oem12c patching -OOW13
 
Reactors.io
Reactors.ioReactors.io
Reactors.io
 
Extreme Replication - RMOUG Presentation
Extreme Replication - RMOUG PresentationExtreme Replication - RMOUG Presentation
Extreme Replication - RMOUG Presentation
 

Similar to JDBC Next: A New Asynchronous API for Connecting to a Database

Silicon Valley JUG meetup July 18, 2018
Silicon Valley JUG meetup July 18, 2018Silicon Valley JUG meetup July 18, 2018
Silicon Valley JUG meetup July 18, 2018
Oracle Developers
 
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Oracle Developers
 
ADBA (Asynchronous Database Access)
ADBA (Asynchronous Database Access)ADBA (Asynchronous Database Access)
ADBA (Asynchronous Database Access)
Logico
 
War of the Indices- SQL vs. Oracle
War of the Indices-  SQL vs. OracleWar of the Indices-  SQL vs. Oracle
War of the Indices- SQL vs. Oracle
Kellyn Pot'Vin-Gorman
 
Data access
Data accessData access
Data access
Joshua Yoon
 
Lambdas & Streams
Lambdas & StreamsLambdas & Streams
Lambdas & Streams
C4Media
 
MySQL Quick Dive
MySQL Quick DiveMySQL Quick Dive
MySQL Quick Dive
Sudipta Kumar Sahoo
 
Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3
Simon Ritter
 
Functional Programming With Lambdas and Streams in JDK8
 Functional Programming With Lambdas and Streams in JDK8 Functional Programming With Lambdas and Streams in JDK8
Functional Programming With Lambdas and Streams in JDK8
IndicThreads
 
MySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer GuideMySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer Guide
Morgan Tocker
 
Oracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overviewOracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overview
Dave Segleau
 
The Power of Relationships in Your Big Data
The Power of Relationships in Your Big DataThe Power of Relationships in Your Big Data
The Power of Relationships in Your Big DataPaulo Fagundes
 
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
jaxLondonConference
 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web Services
Arun Gupta
 
20171104 hk-py con-mysql-documentstore_v1
20171104 hk-py con-mysql-documentstore_v120171104 hk-py con-mysql-documentstore_v1
20171104 hk-py con-mysql-documentstore_v1
Ivan Ma
 
20180420 hk-the powerofmysql8
20180420 hk-the powerofmysql820180420 hk-the powerofmysql8
20180420 hk-the powerofmysql8
Ivan Ma
 
What's New MySQL 8.0?
What's New MySQL 8.0?What's New MySQL 8.0?
What's New MySQL 8.0?
OracleMySQL
 
Advanced SQL - Database Access from Programming Languages
Advanced SQL - Database Access  from Programming LanguagesAdvanced SQL - Database Access  from Programming Languages
Advanced SQL - Database Access from Programming Languages
S.Shayan Daneshvar
 
Java ee7 1hour
Java ee7 1hourJava ee7 1hour
Java ee7 1hour
Frank Rodriguez
 
Optimizer percona live_ams2015
Optimizer percona live_ams2015Optimizer percona live_ams2015
Optimizer percona live_ams2015
Manyi Lu
 

Similar to JDBC Next: A New Asynchronous API for Connecting to a Database (20)

Silicon Valley JUG meetup July 18, 2018
Silicon Valley JUG meetup July 18, 2018Silicon Valley JUG meetup July 18, 2018
Silicon Valley JUG meetup July 18, 2018
 
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
 
ADBA (Asynchronous Database Access)
ADBA (Asynchronous Database Access)ADBA (Asynchronous Database Access)
ADBA (Asynchronous Database Access)
 
War of the Indices- SQL vs. Oracle
War of the Indices-  SQL vs. OracleWar of the Indices-  SQL vs. Oracle
War of the Indices- SQL vs. Oracle
 
Data access
Data accessData access
Data access
 
Lambdas & Streams
Lambdas & StreamsLambdas & Streams
Lambdas & Streams
 
MySQL Quick Dive
MySQL Quick DiveMySQL Quick Dive
MySQL Quick Dive
 
Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3
 
Functional Programming With Lambdas and Streams in JDK8
 Functional Programming With Lambdas and Streams in JDK8 Functional Programming With Lambdas and Streams in JDK8
Functional Programming With Lambdas and Streams in JDK8
 
MySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer GuideMySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer Guide
 
Oracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overviewOracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overview
 
The Power of Relationships in Your Big Data
The Power of Relationships in Your Big DataThe Power of Relationships in Your Big Data
The Power of Relationships in Your Big Data
 
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web Services
 
20171104 hk-py con-mysql-documentstore_v1
20171104 hk-py con-mysql-documentstore_v120171104 hk-py con-mysql-documentstore_v1
20171104 hk-py con-mysql-documentstore_v1
 
20180420 hk-the powerofmysql8
20180420 hk-the powerofmysql820180420 hk-the powerofmysql8
20180420 hk-the powerofmysql8
 
What's New MySQL 8.0?
What's New MySQL 8.0?What's New MySQL 8.0?
What's New MySQL 8.0?
 
Advanced SQL - Database Access from Programming Languages
Advanced SQL - Database Access  from Programming LanguagesAdvanced SQL - Database Access  from Programming Languages
Advanced SQL - Database Access from Programming Languages
 
Java ee7 1hour
Java ee7 1hourJava ee7 1hour
Java ee7 1hour
 
Optimizer percona live_ams2015
Optimizer percona live_ams2015Optimizer percona live_ams2015
Optimizer percona live_ams2015
 

More from Yolande Poirier

Social Media Secrets
Social Media Secrets Social Media Secrets
Social Media Secrets
Yolande Poirier
 
Way to Ally for Women in Java
Way to Ally for Women in Java Way to Ally for Women in Java
Way to Ally for Women in Java
Yolande Poirier
 
Way to Ally for Women in Technology!
Way to Ally for Women in Technology! Way to Ally for Women in Technology!
Way to Ally for Women in Technology!
Yolande Poirier
 
Twitter for developers
Twitter for developers  Twitter for developers
Twitter for developers
Yolande Poirier
 
Java us tour 2017
Java us tour 2017Java us tour 2017
Java us tour 2017
Yolande Poirier
 
More java community insider secrets
More java community insider secretsMore java community insider secrets
More java community insider secrets
Yolande Poirier
 
Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015 Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015
Yolande Poirier
 
Java Community and Overview Track - March 2016
Java Community and Overview Track - March 2016Java Community and Overview Track - March 2016
Java Community and Overview Track - March 2016
Yolande Poirier
 
Java Community News - September 2015
Java Community News - September 2015Java Community News - September 2015
Java Community News - September 2015
Yolande Poirier
 
Oracle Academy and ThinkQuest - Java Summer Workshop 2011
Oracle Academy and ThinkQuest - Java Summer Workshop 2011Oracle Academy and ThinkQuest - Java Summer Workshop 2011
Oracle Academy and ThinkQuest - Java Summer Workshop 2011Yolande Poirier
 
Java summer workshop
Java summer workshop Java summer workshop
Java summer workshop
Yolande Poirier
 

More from Yolande Poirier (11)

Social Media Secrets
Social Media Secrets Social Media Secrets
Social Media Secrets
 
Way to Ally for Women in Java
Way to Ally for Women in Java Way to Ally for Women in Java
Way to Ally for Women in Java
 
Way to Ally for Women in Technology!
Way to Ally for Women in Technology! Way to Ally for Women in Technology!
Way to Ally for Women in Technology!
 
Twitter for developers
Twitter for developers  Twitter for developers
Twitter for developers
 
Java us tour 2017
Java us tour 2017Java us tour 2017
Java us tour 2017
 
More java community insider secrets
More java community insider secretsMore java community insider secrets
More java community insider secrets
 
Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015 Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015
 
Java Community and Overview Track - March 2016
Java Community and Overview Track - March 2016Java Community and Overview Track - March 2016
Java Community and Overview Track - March 2016
 
Java Community News - September 2015
Java Community News - September 2015Java Community News - September 2015
Java Community News - September 2015
 
Oracle Academy and ThinkQuest - Java Summer Workshop 2011
Oracle Academy and ThinkQuest - Java Summer Workshop 2011Oracle Academy and ThinkQuest - Java Summer Workshop 2011
Oracle Academy and ThinkQuest - Java Summer Workshop 2011
 
Java summer workshop
Java summer workshop Java summer workshop
Java summer workshop
 

Recently uploaded

Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
Jen Stirrup
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
UiPathCommunity
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Enhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZEnhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZ
Globus
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
Peter Spielvogel
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
Alex Pruden
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 

Recently uploaded (20)

Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Enhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZEnhancing Performance with Globus and the Science DMZ
Enhancing Performance with Globus and the Science DMZ
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 

JDBC Next: A New Asynchronous API for Connecting to a Database

  • 1.
  • 2.
  • 3. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | JDBC Next: A New Asynchronous API for Connecting to a Database CON1491 Douglas Surber JDBC Architect Oracle Database Server Technologies October 3, 2017 3
  • 4. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Safe Harbor Statement The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.
  • 5. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Program Agenda Overview1 2 3 4 Confidential – Oracle Internal/Restricted/Highly Restricted 5 Code Wrap-up Q&A
  • 6. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Overview 6
  • 7. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Asynchronous Database Access • Java standard database access API that never blocks user threads • Developed by the JDBC Expert Group with community input • Targeted for a near future release, Java 10 or equivalent • Asynchronous apps have better throughput – Fewer threads means less thread scheduling, less thread contention – Database access is slow so blocked threads leave resources idle for a long time – Simultaneous access to multiple databases, e.g. map/reduce, sharded databases – Fire and forget, e.g. DMS, stored procedures 7
  • 8. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Goals • No user thread blocks ever – Minimize the number of threads used for database access • Alternate API for database access – Not an extension of the standard JDBC API – Not a replacement for the standard JDBC API • Target high throughput apps – Not a completely general purpose database access API – The initial version will have a limited feature set • Build on the Java SE class library 8
  • 9. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Design Choices • Minimal or no reference to java.sql • Rigorous use of types • Builder pattern • Fluent API • Immutable after initialization • One way to do something is enough • Avoid SQL processing • Avoid callback hell 9
  • 10. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | What About … ? • Streams – Java streams are inherently synchronous • ReactiveStreams – Not integrated into the Java SE class library • NodeJS • ADBCJ There are already multiple asynchronous/non-blocking database access APIs 10
  • 11. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Code 11
  • 12. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public void trivialInsert(DataSource ds) { String sql = "insert into tab values (:id, :name, :answer)"; try (Connection conn = ds.getConnection()) { conn.countOperation(sql) .set("id", 1, JdbcType.NUMERIC) .set("name", "Deep Thought", JdbcType.VARCHAR) .set("answer", 42, JdbcType.NUMERIC) .submit(); } } Trivial Insert 12
  • 13. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | All SQL is Vendor Specific • No escape sequences • No specified parameter markers • Non vendor specific syntax requires processing by the driver – Adds overhead – Increases code complexity – Minimal benefit as most apps are tied to a specific database regardless Note: Code examples use parameter markers from a variety of databases including DB2 (:foo), MySQL (?), Oracle Database(:foo), PostgresSQL($1), and SQL Server (@foo). 13
  • 14. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public void trivialSelect(DataSource ds, List<Integer> result) { String sql = "select id, name, answer " + "from tab where answer = $1"; try (Connection conn = ds.getConnection()) { conn.<List<Integer>>rowOperation(sql) .set("1", 42, JdbcType.NUMERIC) .rowAggregator( (ignore, row) -> { result.add(row.get("id", Integer.class)); return null; } ) .submit(); } } Trivial Select 14
  • 15. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Execution Model • Operations consist of – SQL or other database operation – Parameter assignments – Result handling – Submission and CompletableFuture • User thread creates and submits Operations – Creating and submitting never blocks; user thread never blocks • Implementation executes those Operations asynchronously – Performs round trip(s) to the database – Executes result handling – Completes CompletableFutures 15 Everything is an Operation
  • 16. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public DataSource getDataSource(String url, String user, String pass) { return DataSourceFactory.forName("Oracle Database") .builder() .url("oracle:database:@//javaone.oracle.com:5521/javaone") .username("scott") .password("tiger") .connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION, TransactionIsolation.SERIALIZABLE) .build(); } Getting a DataSource 16
  • 17. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | in interface DataSource: public default Connection getConnection() { return builder().build().connect(); } in interface Connection: public default Connection connect() { holdForMoreMembers(); submit(); connectOperation().submit(); return this; } Getting a Connection 17
  • 18. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public Future<Integer> selectIdForAnswer(DataSource ds, int answer) { String sql = "select id, name, answer from tab " + "where answer = @target"; try (Connection conn = ds.getConnection()) { return conn.<List<Integer>>rowOperation(sql) .set("target", 42, JdbcType.NUMERIC) .initialValue( () -> new ArrayList<>() ) .rowAggregator( (list, row) -> { list.add(row.get("id", Integer.class)); return list; } ) .submit() .toCompletableFuture() .thenApply( l -> l.get(0) ); } } Basic SELECT 18
  • 19. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public static class Item { protected int id; protected String name; protected int answer; @SqlColumns( { “ID”, “USER”, “RESPONSE” } ) public Item(int id, String name, int answer) { this.id = id; this.name = name; this.answer = answer; } (cont.) POJOs 19
  • 20. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | @SqlParameter(marker=”id”, sqlType="NUMERIC") public int getId() { return id; } @SqlParameter(marker=”name”, sqlType="VARCHAR") public String getName() { return name; } @SqlParameter(marker=”answer”, sqlType="NUMERIC") public int getAnswer() { return answer; } } POJOs (cont.) 20
  • 21. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public void insertListIndependent(List<Item> list, DataSource ds) { String sql = "insert into tab values " + "(:elem_id, :elem_name, :elem_answer)"; try (Connection conn = ds.getConnection()) { BatchCountOperation batch = conn.batchCountOperation(sql); list.forEach( (elem) -> { batch.countOperation() .set("elem_", elem) .submit(); }); batch.submit(); } } Batch Insert 21
  • 22. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | OperationGroup • OperationGroup has its own result handling and CompletableFuture • Members submitted to group. OperationGroup is submitted as a unit • Order of execution – Sequential in order submitted – Parallel, any order • Error response – Dependent: remaining group members skipped – Independent: remaining group members unaffected • Conditional or unconditional • Connection is an OperationGroup – Sequential, dependent, unconditional by default 22 Operations can be grouped
  • 23. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public void insertListHold(List<Item> list, DataSource ds) { String sql = "insert into tab " + "values (@elem_id, @elem_name, @elem_answer)"; try (Connection conn = ds.getConnection()) { OperationGroup group = conn.operationGroup() .holdForMoreMembers() .independent(); group.submit(); (cont.) Independent INSERT 23
  • 24. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | for (Item elem : list) { group.countOperation(sql) .set("elem_", elem) .submit() .toCompletableFuture() .exceptionally( t -> { System.out.println(elem.getId()); return null; }); } group.releaseProhibitingMoreMembers(); } } Independent Insert (cont.) 24
  • 25. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | in interface Connection public default void close() { closeOperation().submit(); releaseProhibitingMoreMembers(); } Note: A CloseOperation is never skipped. Close 25
  • 26. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | in interface Connection public Connection activate(); public Connection deactivate(); public registerLifecycleListener(LifecycleListener listener); Connection Pooling 26
  • 27. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public DataSource getDataSource(String url, String user, String pass) { return DataSourceFactory.forName("Oracle Database") .builder() .url("oracle:database:@//javaone.oracle.com:5521/javaone") .username("scott") .password("tiger") .connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION, TransactionIsolation.SERIALIZABLE) .connectionProperty(NLS_LANGUAGE, “French”) .build(); } ConnectionProperties 27
  • 28. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public static class NlsLanguageProperty implements ConnectionProperty { public static final ConnectionProperty NLS_LANGUAGE = new NlsLanguageProperty(); private NlsLanguageProperty() {} public String name() { return “NLS_LANGUAGE”; } public Class range() { return String.class; } public String defaultValue() { return “American”; } public boolean isSensitive() { return false; } public Operation configureOperation(OperationGroup group, Object value) { String sql = “ALTER SESSION SET NLS_LANGUAGE TO “ + value; return group.operation(sql); } ConnectionProperty 28
  • 29. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | @SqlArray(elementSqlTypeName=”STUDENT”) public class Roster extends LinkedList<Student> { public Roster() {}; } @SqlStruct(sqlTypeName=”STUDENT”, fields={ @Field(sqlFieldName=”NAME”, sqlTypeName=”VARCHAR(100)”, javaFieldName=”name”), @Field(sqlFieldName=”EMAIL”, sqlTypeName=”VARCHAR(100)”, javaFieldName=”email”)}) public class Student { String name; String email; public void setName(String n) {name = n;} public void setEmail(String e) {email = e;} public String getName() {return name;} public String getEmail() {return email;} } ARRAYs and STRUCTs 29
  • 30. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public void transfer(Connection conn, double amount, int fromAccount, int toAccount) { String sql = “update account set balance=balance+@amount where id = @account”; conn.countOperation(sql) .set(“amount”, -amount, JdbcType.DECIMAL) .set(“account”, fromAccount, JdbcType.INTEGER) .submit(); conn.countOperation(sql) .set(“amount”, amount, JdbcType.DECIMAL) .set(“account”, toAccount, JdbcType.INTEGER) .submit(); conn.commit(); } Transactions 30
  • 31. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public void transfer(Connection conn, double amount, int fromAccount, int toAccount) { String sql = “update account set balance=balance+@amount where id = @account”; final Transaction tran = conn.getTransaction(); conn.countOperation(sql) .set(“amount”, -amount, JdbcType.DECIMAL) .set(“account”, fromAccount, JdbcType.INTEGER) .onError( e -> tran.setRollbackOnly() ) .submit(); conn.countOperation(sql) .set(“amount”, amount, JdbcType.DECIMAL) .set(“account”, toAccount, JdbcType.INTEGER) .onError( e -> tran.setRollbackOnly() ) .submit(); conn.commit(); } Transactions (cont.) 31
  • 32. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public void paycheck(Connection conn, Employee emp) { String sql = “call generate_paycheck(?, ?)”; CompletableFuture<CheckDetail> details = conn.<CheckDetail>outOperation(sql) .set(“1”, emp, JdbcType.STRUCT) .outParameter(“2”, JdbcType.STRUCT) .resultProcessor( m -> m.get(“2”, CheckDetail.class) ) .submit() .toCompletableFuture(); conn.localOperation() .onExecution( () -> { printPaycheck(details); return null; } ) .submit() .toCompletableFuture() .thenRun( () -> reportPrintSuccess(details) ); .exceptionally( t -> {reportPrintFailure(details); return null;} ); } Local Operations 32
  • 33. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public void deposit(Connection conn, int accountId, double amount) { String selectSql = “select balance from account where id = $1”; CompletableFuture<Double> newBalanceF = conn <Double>rowOperation(selectSql) .set(“1”, accountId, JdbcType.INTEGER) .rowAggregator( (p, row) -> row.get(“balance”, Double.class) ) .submit() .toCompletableFuture() .thenApply( b -> b + amount ); String updateSql = “update account set balance=$2 where id = $1”; conn.countOperation(updateSql) .set(“1”, accountId, JdbcType.INTEGER) .set(“2”, newBalanceF, JdbcType.DOUBLE) .submit(); } Future Parameters 33
  • 34. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Wrap-up 34
  • 35. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Status • Everything is subject to change • Prototype Oracle Database driver implements much of the API – Uses nio Selector so non-blocking all the way down • Developed by the JDBC Expert Group through the Java Community Process • Targeted for a near future release, Java 10 or equivalent • The API is available for download from OpenJDK at http://oracle.com/goto/java-async-db • Send feedback to jdbc-spec-discuss@openjdk.java.net 35
  • 36. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Q&A 36
  • 37. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | 37
  • 38.
  • 39.
  • 40. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | /* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package test; import java.sql2.BatchCountOperation; import java.sql2.Connection; import java.sql2.ConnectionProperty; import java.sql2.DataSource; import java.sql2.DataSourceFactory; import java.sql2.JdbcConnectionProperty; import java.sql2.JdbcConnectionProperty.TransactionIsolation; import java.sql2.JdbcType; import java.sql2.Operation; import java.sql2.OperationGroup; import java.sql2.SqlArray; import java.sql2.SqlColumns; import java.sql2.SqlParameter; import java.sql2.SqlStruct; import java.sql2.SqlStruct.Field; import java.sql2.Transaction; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.function.Consumer; /** * * Code from JavaOne 2017 slides: CON-1491 * JDBC Next: A New Asynchronous API for Connecting to a Database * */ public class JavaOne { public void trivialInsert(DataSource ds) { String sql = "insert into tab values (:id, :name, :answer)"; try (Connection conn = ds.getConnection()) { conn.countOperation(sql) .set("id", 1, JdbcType.NUMERIC) .set("name", "Deep Thought", JdbcType.VARCHAR) .set("answer", 42, JdbcType.NUMERIC) .submit(); } } public void trivialSelect(DataSource ds, List<Integer> result) { String sql = "select id, name, answer " + "from tab where answer = $1"; try (Connection conn = ds.getConnection()) { conn.<List<Integer>>rowOperation(sql) .set("1", 42, JdbcType.NUMERIC) .rowAggregator((ignore, row) -> { result.add(row.get("id", Integer.class)); return null; }) .submit(); } } public DataSource getDataSource(String url, String user, String pass) { return DataSourceFactory.forName("Oracle Database") .builder() .url("oracle:database:@//javaone.oracle.com:5521/javaone") .username("scott") .password("tiger") .connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION, TransactionIsolation.SERIALIZABLE) .build(); } public Future<Integer> selectIdForAnswer(DataSource ds, int answer) { String sql = "select id, name, answer from tab " + "where answer = @target"; try (Connection conn = ds.getConnection()) { return conn.<List<Integer>>rowOperation(sql) .set("target", 42, JdbcType.NUMERIC) .initialValue(() -> new ArrayList<>()) .rowAggregator((list, row) -> { list.add(row.get("id", Integer.class)); return list; }) .submit() .toCompletableFuture() .thenApply(l -> l.get(0)); } } public void insertListIndependent(List<Item> list, DataSource ds) { String sql = "insert into tab values " + "(:elem_id, :elem_name, :elem_answer)"; try (Connection conn = ds.getConnection()) { BatchCountOperation batch = conn.batchCountOperation(sql); list.forEach((elem) -> { batch.countOperation() .set("elem_", elem) .submit(); }); batch.submit(); } } public void insertListHold(List<Item> list, DataSource ds) { String sql = "insert into tab " + "values (@elem_id, @elem_name, @elem_answer)"; try (Connection conn = ds.getConnection()) { OperationGroup group = conn.operationGroup() .holdForMoreMembers() .independent(); group.submit(); for (Item elem : list) { group.countOperation(sql) .set("elem_", elem) .submit() .toCompletableFuture() .exceptionally(t -> { System.out.println(elem.getId()); return null; }); } group.releaseProhibitingMoreMembers(); } } public DataSource getDataSource_2(String url, String user, String pass) { return DataSourceFactory.forName("Oracle Database") .builder() .url("oracle:database:@//javaone.oracle.com:5521/javaone") .username("scott") .password("tiger") .connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION, TransactionIsolation.SERIALIZABLE) .connectionProperty(NlsLanguageProperty.NLS_LANGUAGE, "French") .build(); } public void transfer(Connection conn, double amount, int fromAccount, int toAccount) { String sql = "update account set balance=balance+@amount where id = @account"; conn.countOperation(sql) .set("amount", -amount, JdbcType.DECIMAL) .set("account", fromAccount, JdbcType.INTEGER) .submit(); conn.countOperation(sql) .set("amount", amount, JdbcType.DECIMAL) .set("account", toAccount, JdbcType.INTEGER) .submit(); conn.commit(); } public void transfer_2(Connection conn, double amount, int fromAccount, int toAccount) { String sql = "update account set balance=balance+@amount where id = @account"; final Transaction tran = conn.getTransaction(); conn.countOperation(sql) .set("amount", -amount, JdbcType.DECIMAL) .set("account", fromAccount, JdbcType.INTEGER) .onError(e -> tran.setRollbackOnly()) .submit(); conn.countOperation(sql) .set("amount", amount, JdbcType.DECIMAL) .set("account", toAccount, JdbcType.INTEGER) .onError(e -> tran.setRollbackOnly()) .submit(); conn.commit(); } public void paycheck(Connection conn, Employee emp) { String sql = "call generate_paycheck(?, ?)"; CompletableFuture<CheckDetail> details = conn.<CheckDetail>outOperation(sql) .set("1", emp, JdbcType.STRUCT) .outParameter("2", JdbcType.STRUCT) .resultProcessor(m -> m.get("2", CheckDetail.class)) .submit() .toCompletableFuture(); conn.localOperation() .onExecution(() -> { printPaycheck(details); return null; }) .submit() .toCompletableFuture() .thenRun(() -> reportPrintSuccess(details)) .exceptionally(t -> { reportPrintFailure(details); return null; }); }
  • 41. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | public void deposit(Connection conn, int accountId, double amount) { String selectSql = "select balance from account where id = $1"; CompletableFuture<Double> newBalanceF = conn.<Double>rowOperation(selectSql) .set("1", accountId, JdbcType.INTEGER) .rowAggregator((p, row) -> row.get("balance", Double.class)) .submit() .toCompletableFuture() .thenApply(b -> b + amount); String updateSql = "update account set balance=$2 where id = $1"; conn.countOperation(updateSql) .set("1", accountId, JdbcType.INTEGER) .set("2", newBalanceF, JdbcType.DOUBLE) .submit(); } public static class Item { protected int id; protected String name; protected int answer; @SqlColumns({"ID", "USER", "RESPONSE"}) public Item(int id, String name, int answer) { this.id = id; this.name = name; this.answer = answer; } @SqlParameter(marker = "id", sqlType = "NUMERIC") public int getId() { return id; } @SqlParameter(marker = "name", sqlType = "VARCHAR") public String getName() { return name; } @SqlParameter(marker = "answer", sqlType = "NUMERIC") public int getAnswer() { return answer; } } public static class NlsLanguageProperty implements ConnectionProperty { public static final ConnectionProperty NLS_LANGUAGE = new NlsLanguageProperty(); private NlsLanguageProperty() { } @Override public String name() { return "NLS_LANGUAGE"; } @Override public Class range() { return String.class; } @Override public String defaultValue() { return "American"; } @Override public boolean isSensitive() { return false; } @Override public Operation configureOperation(OperationGroup group, Object value) { String sql = "ALTER SESSION SET NLS_LANGUAGE TO " + value; return group.operation(sql); } } @SqlArray(elementSqlTypeName = "STUDENT") public static class Roster extends LinkedList<Student> { public Roster() { } } @SqlStruct(sqlTypeName = "STUDENT", fields = { @Field(sqlFieldName = "NAME", sqlTypeName = "VARCHAR(100)", javaFieldName = "name"), @Field(sqlFieldName = "EMAIL", sqlTypeName = "VARCHAR(100)", javaFieldName = "email")}) public class Student { String name; String email; public void setName(String n) { name = n; } public void setEmail(String e) { email = e; } public String getName() { return name; } public String getEmail() { return email; } } public class Employee { } public class CheckDetail { } private void printPaycheck(Future<CheckDetail> checkF) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } private Consumer<? super Object> reportPrintSuccess(Future<CheckDetail> checkF) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } private CompletableFuture<Void> reportPrintFailure(Future<CheckDetail> checkF) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }