KEMBAR78
Application Continuity with Oracle DB 12c | ODP
Understanding Application
Continuity
● Those slides are Leopold Gault's personal
notes and drawings, about application
continuity.
● You can see my sources, and comments in the
slides' notes.
● You may ask me for the original file at
galeopold@gmail.com
● Views expressed here are my own and do not
necessarily reflect the views of Oracle.
Understand Application Continuity
I. javax.sql.DataSource implementations
1) Understanding JDBC drivers
2) Connection pools and JDBC drivers
3) Weblogic Data Sources and JDBC drivers
4) How an app gets a connection a from Welogic Data Source
II. Application Continuity
1) How AC works
● What happens at run-time
● What happens when the connection is interrupted
2) Demo
● AC while fetching data from the cursor of a result set
● AC while performing a local transation
3) Notes About AC
● Notes about Global Transactions
javax.sql.DataSource
Understanding Data Sources and JDBC drivers
JVM
Used by the app
javax.sql.DataSource
interface
JVM
connection factory class a.k.a. JDBC driver
Implements
javax.sql.DataSource interface
Used by the app
« Connection facrory » or « JDBC driver » ?
Features of the
JDBC driver
Connection
Factory feature
JVM
JDBC connection
JDBC driver
Implements javax.sql.DataSource interface
.getConnection()
JVM
Connection pool
JDBC driver
Implements
DataSource interface
Often includes
Read the notes to access my sources
Connection Pool
Its interface Extends javax.sql.DataSource
JVM
Standalone JDBC app
JDBC driver
Implements
DataSource interface
Actually, I think that the JDBC driver can be used both
● in a standalone manner (the app is then called « standalone JDBC application »)
● or configured as the connection factory of a connection pool, such as UCP or
Weblogic Server connection pool.
source
Directly uses
Jdbc driver
Implements javax.sql.DataSource
JVM
Middle-tier JVM
The UCP oracle.ucp.jdbc.PoolDataSourceImpl is
used to manipulate the JDBC driver (a.k.a.
connection factory).
The app doesn't directly asks
the JDBC driver for a connection.
It asks the connection pool.
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
System.out.println("connection factory set");
String URL = "jdbc:oracle:thin:@(DESCRIPTION = (TRANSPORT_CONNECT_TIMEOUT=3)
(RETRY_COUNT=20)(FAILOVER=ON) " +
(ADDRESS = (PROTOCOL = TCP)(HOST = rac12scan.gns.example.com)(PORT = 1521)) (CONNECT_DATA
= " +
(SERVER = DEDICATED) (SERVICE_NAME = ACTEST)))";
System.out.println("Using URLn" + URL);
pds.setURL(URL);
pds.setUser("martin");
pds.setPassword("***");
pds.setInitialPoolSize(10);
pds.setMinPoolSize(10);
pds.setMaxPoolSize(20);
// RAC Features
pds.setConnectionPoolName("Application Continuity Pool");
pds.setFastConnectionFailoverEnabled(true);
// use srvctl config nodeapps to get the ONS ports on the cluster
pds.setONSConfiguration("nodes=192.168.100.30:6200,192.168.100.32:6200");
System.out.println("pool configured, trying to get a connection");
Connection conn = pds.getConnection();
if (conn == null || !((ValidConnection) conn).isValid()) {
System.out.println("connection is not valid");
throw new Exception ("invalid connection obtained from the pool");
}
source
JDBC driver class name
Universal Connection Pool
Universal Connection Pool
Its interface Extends javax.sql.DataSource
Jdbc driver
Implements javax.sql.DataSource
Weblogic
Weblogic Data Source Connection Pool
Its interface extends DataSource interface[2]
I assume that the concept is the same
for Weblogic Data Source Connection
Pool: it is a class that manipulates the
JDBC driver in order to maintain a
connection pool.
Looked-up by the app thanks to its JNDI name
Weblogic Data Source
calling it « Weblogic Server Connection Pool » would make more sense! [1]
Jdbc driver
Implements javax.sql.DataSource
Weblogic
Weblogic Data Source
Its interface extends DataSource interface
Java app
The app looks up the Data Source
thanks to its JNDI name
1)
import javax.sql.DataSource;
public class dbUtilities {
public dbUtilities() {
super();
}
public static final Long getDatabaseId (String seqName) {
DataSource dataSource = null;
Context ic = null;
PreparedStatement stmt = null;
ResultSet rs = null;
Long dbId = null;
String selectString;
selectString = "SELECT " + seqName + ".nextval FROM DUAL";
try {
ic = new InitialContext();
dataSource = (DataSource) ic.lookup("jdbc/AlphaOfficeAccessDS");
} catch (NamingException e) {
}
System.out.println("lookup dataSource returned " + dataSource);
try {
Connection connection = dataSource.getConnection();
,,,,,
Jdbc driver
Implements javax.sql.DataSource
Weblogic
Java app The app asks the Data Source
for a new connection
2)
Weblogic Data Source
Its interface extends javax.sql.DataSource interface
Jdbc replay driver
Implements javax.sql.DataSource
Weblogic
Java app
3)
Weblogic Data Source
Its interface extends javax.sql.DataSource interface
Jdbc replay driver
Implements javax.sql.DataSource
A connection is given
from the Connection pool.
This is called a check-out
Weblogic
Java app
The app can now
access the DB
4)
Weblogic Data Source
Its interface extends javax.sql.DataSource interface
Jdbc replay driver
Implements javax.sql.DataSource
Weblogic
Java app
Everything (all the
database calls)
that happens on
the connection
object between
the check-out and
the check-in is
called a request
[1]
Weblogic Data Source
Its interface extends javax.sql.DataSource interface
Jdbc replay driver
Implements javax.sql.DataSource
Check-out
Check-in
Understand Application Continuity
I. javax.sql.DataSource implementations
1) Understanding JDBC drivers
2) Connection pools and JDBC drivers
3) Weblogic Data Sources and JDBC drivers
4) How an app gets a connection a from Welogic Data Source
II. Application Continuity
1) How AC works
● What happens at run-time
● What happens when the connection is interrupted
2) Demo
● AC while fetching data from the cursor of a result set
● AC while performing a local transation
3) Notes About AC
● Notes about Global Transactions
2] Application Continuity
How to use the JDBC replay driver
In order to benefit from Application Continuity, you have to get a connection from the JDBC replay
driver, whether it is usued by a connection pool (Weblogic JDBC Data Source, UCP, or 3rd
party
connection pool), or directly used by the application (JDBC standalone app)
Connection Pool
Its interface Extends javax.sql.DataSource
JVM
Standalone JDBC app
JDBC driver
Implements
DataSource interface
Directly uses
Jdbc driver
Implements javax.sql.DataSource
JVM
Weblogic
In order to benefit from Application Continuity, you have to get a connection from the JDBC replay
driver, whether it is usued by a connection pool (Weblogic JDBC Data Source, UCP, or 3rd
party
connection pool), or directly used by the application (JDBC standalone app)
Weblogic Data Source
Its interface extends DataSource interface
Jdbc driver
Implements javax.sql.DataSource
JVM
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
pds.setConnectionFactoryClassName("oracle.jdbc.replay.OracleDataSourceImpl");
System.out.println("connection factory set");
String URL = "jdbc:oracle:thin:@(DESCRIPTION = (TRANSPORT_CONNECT_TIMEOUT=3) (RETRY_COUNT=20)
(FAILOVER=ON) " +
(ADDRESS = (PROTOCOL = TCP)(HOST = rac12scan.gns.example.com)(PORT = 1521)) (CONNECT_DATA = " +
(SERVER = DEDICATED) (SERVICE_NAME = ACTEST)))";
System.out.println("Using URLn" + URL);
pds.setURL(URL);
pds.setUser("martin");
pds.setPassword("***");
pds.setInitialPoolSize(10);
pds.setMinPoolSize(10);
pds.setMaxPoolSize(20);
// RAC Features
pds.setConnectionPoolName("Application Continuity Pool");
pds.setFastConnectionFailoverEnabled(true);
// use srvctl config nodeapps to get the ONS ports on the cluster
pds.setONSConfiguration("nodes=192.168.100.30:6200,192.168.100.32:6200");
System.out.println("pool configured, trying to get a connection");
Connection conn = pds.getConnection();
if (conn == null || !((ValidConnection) conn).isValid()) {
System.out.println("connection is not valid");
throw new Exception ("invalid connection obtained from the pool");
}
source
JDBC replay driver class name
In order to benefit from Application Continuity, you have to get a connection from the JDBC replay
driver, whether it is usued by a connection pool (Weblogic JDBC Data Source, UCP, or 3rd
party
connection pool), or directly used by the application (JDBC standalone app)
Universal Connection Pool
Jdbc driver
Implements javax.sql.DataSource
Note that if you use connections that do not come from an Oracle connection pool (Weblogic Data Source or UCP,
etc.), but instead come from a third party connection pool, you have to add beginRequest and endRequest APIs to the
application's own connection pool to identify request boundaries. [1]
import java.sql.Connection;
import javax.sql.PooledConnection;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.replay.OracleDataSourceFactory;
import oracle.jdbc.replay.OracleDataSource;
import oracle.jdbc.replay.OracleConnectionPoolDataSource;
...
{
......
OracleDataSource rds = OracleDataSourceFactory.getOracleDataSource();
rds.setUser(user);
rds.setPassword(passwd);
rds.setURL(url);
...... // Other data source configuration like callback, timeouts, etc.
Connection conn = rds.getConnection();
((OracleConnection) conn).beginRequest(); // Explicit request begin
...... // JDBC calls protected by Application Continuity
((OracleConnection) conn).endRequest(); // Explicit request end
conn.close();
OracleConnectionPoolDataSource rcpds = OracleDataSourceFactory.getOracleConnectionPoolDataSource();
rcpds.setUser(user);
rcpds.setPassword(passwd);
rcpds.setURL(url);
...... // other data source configuration like callback, timeouts, and so on
PooledConnection pc = rcpds.getPooledConnection();
Connection conn2 = pc.getConnection(); // Implicit request begin
...... // JDBC calls protected by Application Continuity
conn2.close(); // Implicit request end
source
JDBC replay driver interface name
Here we use the
replay-driver directly
so we have to add
beginRequest()
Here we use an Oracle
connection pool, so no
need to add
beginRequest()
JVM
JDBC replay driver
Implements
DataSource interface
Standalone jdbc app
directly uses
Note that if you use connections that do not come from an Oracle connection pool (Weblogic Data Source or UCP,
etc.), but instead come from a third party connection pool, you have to add beginRequest and endRequest APIs to the
application's own connection pool to identify request boundaries. [1]
import java.sql.Connection;
import javax.sql.PooledConnection;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.replay.OracleDataSourceFactory;
import oracle.jdbc.replay.OracleDataSource;
import oracle.jdbc.replay.OracleConnectionPoolDataSource;
...
{
......
OracleDataSource rds = OracleDataSourceFactory.getOracleDataSource();
rds.setUser(user);
rds.setPassword(passwd);
rds.setURL(url);
...... // Other data source configuration like callback, timeouts, etc.
Connection conn = rds.getConnection();
((OracleConnection) conn).beginRequest(); // Explicit request begin
...... // JDBC calls protected by Application Continuity
((OracleConnection) conn).endRequest(); // Explicit request end
conn.close();
OracleConnectionPoolDataSource rcpds = OracleDataSourceFactory.getOracleConnectionPoolDataSource();
rcpds.setUser(user);
rcpds.setPassword(passwd);
rcpds.setURL(url);
...... // other data source configuration like callback, timeouts, and so on
PooledConnection pc = rcpds.getPooledConnection();
Connection conn2 = pc.getConnection(); // Implicit request begin
...... // JDBC calls protected by Application Continuity
conn2.close(); // Implicit request end
source
JDBC replay driver interface name
Note that if you use the jdbc replay driver in a stand alone
manner, you also have to add beginRequest/endRequest [2]
Here we use the
replay-driver directly
so we have to add
beginRequest()
Here we use an Oracle
connection pool, so no
need to add
beginRequest()
What happens with the replay driver and DB 12c
at runtime
[source]
2] Application Continuity
Weblogic
Weblogic Data Source
Java app
JDBC driver
Implements
DataSource interface
Used to create connections
Connection pool
The replay-driver
monitors and gets
information from
● the connection
object
● the continuity
director (that sits
inside the
database).
It stores any relevant
information for a
replay, until the end of
the request (when the
connection is sent
back to the connection
pool).
Continuity director
Weblogic
Weblogic Data Source
Java app
JDBC driver
Implements
DataSource interface
Used to create connections
Connection pool
Specifically, the replay-
driver saves all the
PL/SQL statements
that the continuity
director has instructed
it to store. It saves
them into the replay-
context.
For each call made to
the DB, the replay
driver retains the
context required for a
subsequent replay. [1]
Replay
context
PL/SQL
statements
Continuity director
Weblogic
Weblogic Data Source
Java app
JDBC driver
Implements
DataSource interface
Used to create connections
Connection pool
The continuity director also stores
protocol and validation information.
It stores this information locally, on what
seems to be called the « replay context »
too. However, it is probably quite different
from the replay context of the JDBC-
replay-driver.Protocol
and validation
information
? Replay context ?
Continuity director
Tx Guard
Weblogic
Weblogic Data Source
Java app
JDBC driver
Implements
DataSource interface
Used to create connections
Connection pool
Moreover, I think that
both the JDBC replay
driver and the Continuity
director store the logical
transaction IDs (LTXID)
of recent transactions.
The LTXID is provided by
the Transaction Guard
feature of the 12c DB. It
allows to identify logically
a transaction that has
been committed, and to
know its outcome
(committed and
completed or rolledback).
Transaction Guard
therefore stores a history
of past transactions, with
their known outcome.
Continuity director
LTXID SQL
statements
XXXX INSERT ..
DELETE ..
COMMIT
YYYY CREATE
We interrupt the connection by performing a
switchover
Application Continuity
Data Guard
Weblogic
Weblogic Data Source
Java app
JDBC driver
Implements
DataSource interface
Used to create connections
Standby
DB
Connection pool
Primary
DB
We switchover
A switchover is
seen from an
external point of
view as if all the
DB sessions were
killed
Data Guard
Weblogic
Weblogic Data Source
Java app
JDBC driver
Implements
DataSource interface
Used to create connections
Standby
DB
Connection pool
Primary
DB
The app can now
access the DB
The replay-driver
intercepts execution
errors. When the error is
recoverable, the replay-
driver replays the calls
that were performed
since the beginning of
the request. It therefore
restores :
● the cursors as they
were (same position
in the result set),
● and the latest
transaction that was
being build up, as it
was.
Data Guard
Weblogic
Weblogic Data Source
Java app
JDBC driver
Implements
DataSource interface
Used to create connections
Standby
DB
Connection pool
Primary
DB
The app can now
access the DB
Thanks to the replay of the
replay-driver, new DB
sessions have been created
on the new-primary DB.
Those re-created DB-
sessions don't necessarily
have the same SID and
serial number (cf next slide).
But the application keeps on
using the same connection
object (it does not check-out
a new one), so to me, this
means that the replay driver
makes the replacement of
the old connection object by
a new one invisible, by
registering the new
connection object at the
same reference variable.
I guess the replay driver
does the same for the
connections in the
connection pool.
By the way, I think that the
mechanism is the same for
all the objects got out of the
connection object (such as
result-set cursors) : they are
replaced by the replay driver
and registered at the same
reference variable ; so that
the application beleive it's
the same object.
Before we kill all the sessions, here is the
(SID, Serial number) couple of all the existing
database sessions for our application
(SwingBench)
After we killed the sessions, new sessions are
created to replace the killed ones. They don't
necessarily have the same (SID, Serial number)
couple
Application continuity when killing all the db sessions on a single database (no
RAC nor Data Guard)
Weblogic
Weblogic Data Source
Java app
JDBC driver
Implements
DataSource interface
Used to create connections
Connection pool
Replay
context
PL/SQL
statements
Continuity director
Protocol
and validation
information
? Replay context ?
The request is replayed
by the driver, using the
replay context in order
to have the same
context as when the
request was originally
played.
The continuity director
decides whether or
not it accepts a
replay ; both before
and after the replay (I
think).
If the replay is
successful, the
expected response will
be given to the app. It
will look as if there had
been a small time delay.
Tx Guard
Weblogic
Weblogic Data Source
Java app
JDBC driver
Implements
DataSource interface
Used to create connections
Connection pool
Continuity director
LTXID SQL
statements
XXXX INSERT ..
DELETE ..
COMMIT
YYYY CREATE
« Has transaction XXXX been successfully committed ? »
[About transactions] In
order to replay the most
recent transaction that was
asserted during the request,
the replay-driver asks
Transaction Guard if the
transaction has been
successfully committed,
using its logical transaction
ID.
If it was not, the replay driver
can replay the transaction.
This process prevents from
committing two times the
same transaction, and thus
result with data
inconsistency.
Understand Application Continuity
I. javax.sql.DataSource implementations
1) Understanding JDBC drivers
2) Connection pools and JDBC drivers
3) Weblogic Data Sources and JDBC drivers
4) How an app gets a connection a from Welogic Data Source
II. Application Continuity
1) How AC works
● What happens at run-time
● What happens when the connection is interrupted
2) Demo
● AC while fetching data from the cursor of a result set
● AC while performing a local transation
3) Notes About AC
● Notes about Global Transactions
Demo
Scenario 1 :
Restoring an active cursor
Demo
$response = $db->query('SELECT * FROM video_games');
while ($rowData = $response->fetch())
{
echo $rowData['name'];
}
$response->closeCursor();
We switchover during the
execution of the loop
Although AC is only for Java applications, to help you understand what a
cursor does, here is how to use a cursor in PHP :
1)Perform a SELECT query
2)Switchover while the cursor of the result-set is still active
3)Try to fetch the next row of results from the cursor
4)Outcome:
Data Source with AC Data Source without AC
No error is displayed An ORA error is displayed
We can keep on fetching data from the
cursor
The result set is lost
Scenario 2: Restore an in-flight
transaction
Demo
BEGIN
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Ramesh', 32, 'Ahmedabad', 2000.00 );
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (2, 'Khilan', 25, 'Delhi', 1500.00 );
COMMIT
Example of a local transaction
1)Begin a local transaction, and insert some rows
2)Switchover, without previously committing the transaction
3)Try to insert a new row
4)Outcome:
Data Source with AC Data Source without AC
No error is displayed An ORA error is displayed
We can keep on inserting new values, and
finally commit.
The transaction is lost
Understand Application Continuity
I. javax.sql.DataSource implementations
1) Understanding JDBC drivers
2) Connection pools and JDBC drivers
3) Weblogic Data Sources and JDBC drivers
4) How an app gets a connection a from Welogic Data Source
II. Application Continuity
1) How AC works
● What happens at run-time
● What happens when the connection is interrupted
2) Demo
● AC while fetching data from the cursor of a result set
● AC while performing a local transation
3) Notes About AC
● Notes about Global Transactions
Notes about Global Transactions
(JDBC driver)
Notes about Global Transactions for
Application Continuity
● We can only use the non-XA driver
● However you can still enable the JDBC driver to
participate in Global Transactions, by enabling
last logging resource, or single-phase-commit,
or simulate two-phases-commit.

Application Continuity with Oracle DB 12c

  • 1.
    Understanding Application Continuity ● Thoseslides are Leopold Gault's personal notes and drawings, about application continuity. ● You can see my sources, and comments in the slides' notes. ● You may ask me for the original file at galeopold@gmail.com ● Views expressed here are my own and do not necessarily reflect the views of Oracle.
  • 2.
    Understand Application Continuity I.javax.sql.DataSource implementations 1) Understanding JDBC drivers 2) Connection pools and JDBC drivers 3) Weblogic Data Sources and JDBC drivers 4) How an app gets a connection a from Welogic Data Source II. Application Continuity 1) How AC works ● What happens at run-time ● What happens when the connection is interrupted 2) Demo ● AC while fetching data from the cursor of a result set ● AC while performing a local transation 3) Notes About AC ● Notes about Global Transactions
  • 3.
  • 4.
    JVM Used by theapp javax.sql.DataSource interface
  • 5.
    JVM connection factory classa.k.a. JDBC driver Implements javax.sql.DataSource interface Used by the app « Connection facrory » or « JDBC driver » ? Features of the JDBC driver Connection Factory feature
  • 6.
    JVM JDBC connection JDBC driver Implementsjavax.sql.DataSource interface .getConnection()
  • 7.
    JVM Connection pool JDBC driver Implements DataSourceinterface Often includes Read the notes to access my sources
  • 8.
    Connection Pool Its interfaceExtends javax.sql.DataSource JVM Standalone JDBC app JDBC driver Implements DataSource interface Actually, I think that the JDBC driver can be used both ● in a standalone manner (the app is then called « standalone JDBC application ») ● or configured as the connection factory of a connection pool, such as UCP or Weblogic Server connection pool. source Directly uses Jdbc driver Implements javax.sql.DataSource JVM
  • 9.
    Middle-tier JVM The UCPoracle.ucp.jdbc.PoolDataSourceImpl is used to manipulate the JDBC driver (a.k.a. connection factory). The app doesn't directly asks the JDBC driver for a connection. It asks the connection pool. PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); System.out.println("connection factory set"); String URL = "jdbc:oracle:thin:@(DESCRIPTION = (TRANSPORT_CONNECT_TIMEOUT=3) (RETRY_COUNT=20)(FAILOVER=ON) " + (ADDRESS = (PROTOCOL = TCP)(HOST = rac12scan.gns.example.com)(PORT = 1521)) (CONNECT_DATA = " + (SERVER = DEDICATED) (SERVICE_NAME = ACTEST)))"; System.out.println("Using URLn" + URL); pds.setURL(URL); pds.setUser("martin"); pds.setPassword("***"); pds.setInitialPoolSize(10); pds.setMinPoolSize(10); pds.setMaxPoolSize(20); // RAC Features pds.setConnectionPoolName("Application Continuity Pool"); pds.setFastConnectionFailoverEnabled(true); // use srvctl config nodeapps to get the ONS ports on the cluster pds.setONSConfiguration("nodes=192.168.100.30:6200,192.168.100.32:6200"); System.out.println("pool configured, trying to get a connection"); Connection conn = pds.getConnection(); if (conn == null || !((ValidConnection) conn).isValid()) { System.out.println("connection is not valid"); throw new Exception ("invalid connection obtained from the pool"); } source JDBC driver class name Universal Connection Pool Universal Connection Pool Its interface Extends javax.sql.DataSource Jdbc driver Implements javax.sql.DataSource
  • 10.
    Weblogic Weblogic Data SourceConnection Pool Its interface extends DataSource interface[2] I assume that the concept is the same for Weblogic Data Source Connection Pool: it is a class that manipulates the JDBC driver in order to maintain a connection pool. Looked-up by the app thanks to its JNDI name Weblogic Data Source calling it « Weblogic Server Connection Pool » would make more sense! [1] Jdbc driver Implements javax.sql.DataSource
  • 11.
    Weblogic Weblogic Data Source Itsinterface extends DataSource interface Java app The app looks up the Data Source thanks to its JNDI name 1) import javax.sql.DataSource; public class dbUtilities { public dbUtilities() { super(); } public static final Long getDatabaseId (String seqName) { DataSource dataSource = null; Context ic = null; PreparedStatement stmt = null; ResultSet rs = null; Long dbId = null; String selectString; selectString = "SELECT " + seqName + ".nextval FROM DUAL"; try { ic = new InitialContext(); dataSource = (DataSource) ic.lookup("jdbc/AlphaOfficeAccessDS"); } catch (NamingException e) { } System.out.println("lookup dataSource returned " + dataSource); try { Connection connection = dataSource.getConnection(); ,,,,, Jdbc driver Implements javax.sql.DataSource
  • 12.
    Weblogic Java app Theapp asks the Data Source for a new connection 2) Weblogic Data Source Its interface extends javax.sql.DataSource interface Jdbc replay driver Implements javax.sql.DataSource
  • 13.
    Weblogic Java app 3) Weblogic DataSource Its interface extends javax.sql.DataSource interface Jdbc replay driver Implements javax.sql.DataSource A connection is given from the Connection pool. This is called a check-out
  • 14.
    Weblogic Java app The appcan now access the DB 4) Weblogic Data Source Its interface extends javax.sql.DataSource interface Jdbc replay driver Implements javax.sql.DataSource
  • 15.
    Weblogic Java app Everything (allthe database calls) that happens on the connection object between the check-out and the check-in is called a request [1] Weblogic Data Source Its interface extends javax.sql.DataSource interface Jdbc replay driver Implements javax.sql.DataSource Check-out Check-in
  • 16.
    Understand Application Continuity I.javax.sql.DataSource implementations 1) Understanding JDBC drivers 2) Connection pools and JDBC drivers 3) Weblogic Data Sources and JDBC drivers 4) How an app gets a connection a from Welogic Data Source II. Application Continuity 1) How AC works ● What happens at run-time ● What happens when the connection is interrupted 2) Demo ● AC while fetching data from the cursor of a result set ● AC while performing a local transation 3) Notes About AC ● Notes about Global Transactions
  • 17.
    2] Application Continuity Howto use the JDBC replay driver
  • 18.
    In order tobenefit from Application Continuity, you have to get a connection from the JDBC replay driver, whether it is usued by a connection pool (Weblogic JDBC Data Source, UCP, or 3rd party connection pool), or directly used by the application (JDBC standalone app) Connection Pool Its interface Extends javax.sql.DataSource JVM Standalone JDBC app JDBC driver Implements DataSource interface Directly uses Jdbc driver Implements javax.sql.DataSource JVM
  • 19.
    Weblogic In order tobenefit from Application Continuity, you have to get a connection from the JDBC replay driver, whether it is usued by a connection pool (Weblogic JDBC Data Source, UCP, or 3rd party connection pool), or directly used by the application (JDBC standalone app) Weblogic Data Source Its interface extends DataSource interface Jdbc driver Implements javax.sql.DataSource
  • 20.
    JVM PoolDataSource pds =PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionFactoryClassName("oracle.jdbc.replay.OracleDataSourceImpl"); System.out.println("connection factory set"); String URL = "jdbc:oracle:thin:@(DESCRIPTION = (TRANSPORT_CONNECT_TIMEOUT=3) (RETRY_COUNT=20) (FAILOVER=ON) " + (ADDRESS = (PROTOCOL = TCP)(HOST = rac12scan.gns.example.com)(PORT = 1521)) (CONNECT_DATA = " + (SERVER = DEDICATED) (SERVICE_NAME = ACTEST)))"; System.out.println("Using URLn" + URL); pds.setURL(URL); pds.setUser("martin"); pds.setPassword("***"); pds.setInitialPoolSize(10); pds.setMinPoolSize(10); pds.setMaxPoolSize(20); // RAC Features pds.setConnectionPoolName("Application Continuity Pool"); pds.setFastConnectionFailoverEnabled(true); // use srvctl config nodeapps to get the ONS ports on the cluster pds.setONSConfiguration("nodes=192.168.100.30:6200,192.168.100.32:6200"); System.out.println("pool configured, trying to get a connection"); Connection conn = pds.getConnection(); if (conn == null || !((ValidConnection) conn).isValid()) { System.out.println("connection is not valid"); throw new Exception ("invalid connection obtained from the pool"); } source JDBC replay driver class name In order to benefit from Application Continuity, you have to get a connection from the JDBC replay driver, whether it is usued by a connection pool (Weblogic JDBC Data Source, UCP, or 3rd party connection pool), or directly used by the application (JDBC standalone app) Universal Connection Pool Jdbc driver Implements javax.sql.DataSource
  • 21.
    Note that ifyou use connections that do not come from an Oracle connection pool (Weblogic Data Source or UCP, etc.), but instead come from a third party connection pool, you have to add beginRequest and endRequest APIs to the application's own connection pool to identify request boundaries. [1] import java.sql.Connection; import javax.sql.PooledConnection; import oracle.jdbc.OracleConnection; import oracle.jdbc.replay.OracleDataSourceFactory; import oracle.jdbc.replay.OracleDataSource; import oracle.jdbc.replay.OracleConnectionPoolDataSource; ... { ...... OracleDataSource rds = OracleDataSourceFactory.getOracleDataSource(); rds.setUser(user); rds.setPassword(passwd); rds.setURL(url); ...... // Other data source configuration like callback, timeouts, etc. Connection conn = rds.getConnection(); ((OracleConnection) conn).beginRequest(); // Explicit request begin ...... // JDBC calls protected by Application Continuity ((OracleConnection) conn).endRequest(); // Explicit request end conn.close(); OracleConnectionPoolDataSource rcpds = OracleDataSourceFactory.getOracleConnectionPoolDataSource(); rcpds.setUser(user); rcpds.setPassword(passwd); rcpds.setURL(url); ...... // other data source configuration like callback, timeouts, and so on PooledConnection pc = rcpds.getPooledConnection(); Connection conn2 = pc.getConnection(); // Implicit request begin ...... // JDBC calls protected by Application Continuity conn2.close(); // Implicit request end source JDBC replay driver interface name Here we use the replay-driver directly so we have to add beginRequest() Here we use an Oracle connection pool, so no need to add beginRequest()
  • 22.
    JVM JDBC replay driver Implements DataSourceinterface Standalone jdbc app directly uses Note that if you use connections that do not come from an Oracle connection pool (Weblogic Data Source or UCP, etc.), but instead come from a third party connection pool, you have to add beginRequest and endRequest APIs to the application's own connection pool to identify request boundaries. [1] import java.sql.Connection; import javax.sql.PooledConnection; import oracle.jdbc.OracleConnection; import oracle.jdbc.replay.OracleDataSourceFactory; import oracle.jdbc.replay.OracleDataSource; import oracle.jdbc.replay.OracleConnectionPoolDataSource; ... { ...... OracleDataSource rds = OracleDataSourceFactory.getOracleDataSource(); rds.setUser(user); rds.setPassword(passwd); rds.setURL(url); ...... // Other data source configuration like callback, timeouts, etc. Connection conn = rds.getConnection(); ((OracleConnection) conn).beginRequest(); // Explicit request begin ...... // JDBC calls protected by Application Continuity ((OracleConnection) conn).endRequest(); // Explicit request end conn.close(); OracleConnectionPoolDataSource rcpds = OracleDataSourceFactory.getOracleConnectionPoolDataSource(); rcpds.setUser(user); rcpds.setPassword(passwd); rcpds.setURL(url); ...... // other data source configuration like callback, timeouts, and so on PooledConnection pc = rcpds.getPooledConnection(); Connection conn2 = pc.getConnection(); // Implicit request begin ...... // JDBC calls protected by Application Continuity conn2.close(); // Implicit request end source JDBC replay driver interface name Note that if you use the jdbc replay driver in a stand alone manner, you also have to add beginRequest/endRequest [2] Here we use the replay-driver directly so we have to add beginRequest() Here we use an Oracle connection pool, so no need to add beginRequest()
  • 23.
    What happens withthe replay driver and DB 12c at runtime [source] 2] Application Continuity
  • 24.
    Weblogic Weblogic Data Source Javaapp JDBC driver Implements DataSource interface Used to create connections Connection pool The replay-driver monitors and gets information from ● the connection object ● the continuity director (that sits inside the database). It stores any relevant information for a replay, until the end of the request (when the connection is sent back to the connection pool). Continuity director
  • 25.
    Weblogic Weblogic Data Source Javaapp JDBC driver Implements DataSource interface Used to create connections Connection pool Specifically, the replay- driver saves all the PL/SQL statements that the continuity director has instructed it to store. It saves them into the replay- context. For each call made to the DB, the replay driver retains the context required for a subsequent replay. [1] Replay context PL/SQL statements Continuity director
  • 26.
    Weblogic Weblogic Data Source Javaapp JDBC driver Implements DataSource interface Used to create connections Connection pool The continuity director also stores protocol and validation information. It stores this information locally, on what seems to be called the « replay context » too. However, it is probably quite different from the replay context of the JDBC- replay-driver.Protocol and validation information ? Replay context ? Continuity director
  • 27.
    Tx Guard Weblogic Weblogic DataSource Java app JDBC driver Implements DataSource interface Used to create connections Connection pool Moreover, I think that both the JDBC replay driver and the Continuity director store the logical transaction IDs (LTXID) of recent transactions. The LTXID is provided by the Transaction Guard feature of the 12c DB. It allows to identify logically a transaction that has been committed, and to know its outcome (committed and completed or rolledback). Transaction Guard therefore stores a history of past transactions, with their known outcome. Continuity director LTXID SQL statements XXXX INSERT .. DELETE .. COMMIT YYYY CREATE
  • 28.
    We interrupt theconnection by performing a switchover Application Continuity
  • 29.
    Data Guard Weblogic Weblogic DataSource Java app JDBC driver Implements DataSource interface Used to create connections Standby DB Connection pool Primary DB We switchover A switchover is seen from an external point of view as if all the DB sessions were killed
  • 30.
    Data Guard Weblogic Weblogic DataSource Java app JDBC driver Implements DataSource interface Used to create connections Standby DB Connection pool Primary DB The app can now access the DB The replay-driver intercepts execution errors. When the error is recoverable, the replay- driver replays the calls that were performed since the beginning of the request. It therefore restores : ● the cursors as they were (same position in the result set), ● and the latest transaction that was being build up, as it was.
  • 31.
    Data Guard Weblogic Weblogic DataSource Java app JDBC driver Implements DataSource interface Used to create connections Standby DB Connection pool Primary DB The app can now access the DB Thanks to the replay of the replay-driver, new DB sessions have been created on the new-primary DB. Those re-created DB- sessions don't necessarily have the same SID and serial number (cf next slide). But the application keeps on using the same connection object (it does not check-out a new one), so to me, this means that the replay driver makes the replacement of the old connection object by a new one invisible, by registering the new connection object at the same reference variable. I guess the replay driver does the same for the connections in the connection pool. By the way, I think that the mechanism is the same for all the objects got out of the connection object (such as result-set cursors) : they are replaced by the replay driver and registered at the same reference variable ; so that the application beleive it's the same object.
  • 32.
    Before we killall the sessions, here is the (SID, Serial number) couple of all the existing database sessions for our application (SwingBench) After we killed the sessions, new sessions are created to replace the killed ones. They don't necessarily have the same (SID, Serial number) couple Application continuity when killing all the db sessions on a single database (no RAC nor Data Guard)
  • 33.
    Weblogic Weblogic Data Source Javaapp JDBC driver Implements DataSource interface Used to create connections Connection pool Replay context PL/SQL statements Continuity director Protocol and validation information ? Replay context ? The request is replayed by the driver, using the replay context in order to have the same context as when the request was originally played. The continuity director decides whether or not it accepts a replay ; both before and after the replay (I think). If the replay is successful, the expected response will be given to the app. It will look as if there had been a small time delay.
  • 34.
    Tx Guard Weblogic Weblogic DataSource Java app JDBC driver Implements DataSource interface Used to create connections Connection pool Continuity director LTXID SQL statements XXXX INSERT .. DELETE .. COMMIT YYYY CREATE « Has transaction XXXX been successfully committed ? » [About transactions] In order to replay the most recent transaction that was asserted during the request, the replay-driver asks Transaction Guard if the transaction has been successfully committed, using its logical transaction ID. If it was not, the replay driver can replay the transaction. This process prevents from committing two times the same transaction, and thus result with data inconsistency.
  • 35.
    Understand Application Continuity I.javax.sql.DataSource implementations 1) Understanding JDBC drivers 2) Connection pools and JDBC drivers 3) Weblogic Data Sources and JDBC drivers 4) How an app gets a connection a from Welogic Data Source II. Application Continuity 1) How AC works ● What happens at run-time ● What happens when the connection is interrupted 2) Demo ● AC while fetching data from the cursor of a result set ● AC while performing a local transation 3) Notes About AC ● Notes about Global Transactions
  • 36.
  • 37.
    Scenario 1 : Restoringan active cursor Demo
  • 38.
    $response = $db->query('SELECT* FROM video_games'); while ($rowData = $response->fetch()) { echo $rowData['name']; } $response->closeCursor(); We switchover during the execution of the loop Although AC is only for Java applications, to help you understand what a cursor does, here is how to use a cursor in PHP :
  • 39.
    1)Perform a SELECTquery 2)Switchover while the cursor of the result-set is still active 3)Try to fetch the next row of results from the cursor 4)Outcome: Data Source with AC Data Source without AC No error is displayed An ORA error is displayed We can keep on fetching data from the cursor The result set is lost
  • 40.
    Scenario 2: Restorean in-flight transaction Demo
  • 41.
    BEGIN INSERT INTO CUSTOMERS(ID,NAME,AGE,ADDRESS,SALARY) VALUES (1, 'Ramesh', 32, 'Ahmedabad', 2000.00 ); INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY) VALUES (2, 'Khilan', 25, 'Delhi', 1500.00 ); COMMIT Example of a local transaction
  • 42.
    1)Begin a localtransaction, and insert some rows 2)Switchover, without previously committing the transaction 3)Try to insert a new row 4)Outcome: Data Source with AC Data Source without AC No error is displayed An ORA error is displayed We can keep on inserting new values, and finally commit. The transaction is lost
  • 43.
    Understand Application Continuity I.javax.sql.DataSource implementations 1) Understanding JDBC drivers 2) Connection pools and JDBC drivers 3) Weblogic Data Sources and JDBC drivers 4) How an app gets a connection a from Welogic Data Source II. Application Continuity 1) How AC works ● What happens at run-time ● What happens when the connection is interrupted 2) Demo ● AC while fetching data from the cursor of a result set ● AC while performing a local transation 3) Notes About AC ● Notes about Global Transactions
  • 44.
    Notes about GlobalTransactions (JDBC driver)
  • 45.
    Notes about GlobalTransactions for Application Continuity ● We can only use the non-XA driver ● However you can still enable the JDBC driver to participate in Global Transactions, by enabling last logging resource, or single-phase-commit, or simulate two-phases-commit.

Editor's Notes

  • #5 https://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html
  • #6 https://docs.oracle.com/database/121/JJUAR/oracle/ucp/jdbc/PoolDataSourceImpl.html The connection factory class is a class that implements javax.sql.DataSource and does not implement its own connection pooling. The connection factory's getConnection(...) methods should return a physical JDBC connection to the database. For example, "oracle.jdbc.pool.OracleDataSource" is a valid connection factory class name.
  • #8 Source : https://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html « The DataSource interface is implemented by a driver vendor. There are three types of implementations: Basic implementation -- produces a standard Connection object Connection pooling implementation -- produces a Connection object that will automatically participate in connection pooling. This implementation works with a middle-tier connection pooling manager. Distributed transaction implementation -- produces a Connection object that may be used for distributed transactions and almost always participates in connection pooling. This implementation works with a middle-tier transaction manager and almost always with a connection pooling manager.  »  https://docs.oracle.com/javase/tutorial/jdbc/basics/sqldatasources.html « A JDBC driver should include at least a basic Data Source implementation. For example, the Java DB JDBC driver (-Leo : this is the one provided by the JDK, not Weblogic) includes the implementation org.apache.derby.jdbc.ClientData Source and for MySQL, com.mysql.jdbc.jdbc2.optional.MysqlData Source. »
  • #11 [2] that's why we cast the Weblogic Data Source as a javax.sql.DataSource when we look it up from the JNDI import javax.sql.DataSource; ... dataSource = (DataSource) ic.lookup("jdbc/AlphaOfficeAccessDS");
  • #16 1- « In general, a request is demarcated by the calls made between check-out and check-in of a database connection from a connection pool. » https://docs.oracle.com/database/121/CNCPT/transact.htm#CNCPT89323
  • #19 https://docs.oracle.com/database/121/ADFNS/adfns_app_continuity.htm#ADFNS1207
  • #21 https://docs.oracle.com/database/121/ADFNS/adfns_app_continuity.htm#ADFNS1207
  • #22 [1] https://docs.oracle.com/database/121/ADFNS/adfns_app_continuity.htm#ADFNS1207 Determine whether the application borrows and returns connections from the WebLogic Server Pool or Universal Connection Pool for each request, or whether to add beginRequest and endRequest APIs to the application's own connection pool to identify request boundaries. [2]https://docs.oracle.com/database/121/JJDBC/appcontnew.htm#JJDBC29073 You must use either the oracle.jdbc.replay.OracleDataSourceImpl or oracle.jdbc.replay.OracleConnectionPoolDataSourceImpl data source to obtain JDBC connections. They are new Oracle JDBC data sources, and work similarly to the existing non-XA data sources, such as oracle.jdbc.pool.OracleDataSource. You can use both in a standalone manner, or configure them as connection factories for a connection pool, such as Universal Connection Pool (UCP), or Oracle WebLogic Server connection pool.
  • #23 [1] https://docs.oracle.com/database/121/ADFNS/adfns_app_continuity.htm#ADFNS1207 Determine whether the application borrows and returns connections from the WebLogic Server Pool or Universal Connection Pool for each request, or whether to add beginRequest and endRequest APIs to the application's own connection pool to identify request boundaries. [2]https://docs.oracle.com/database/121/JJDBC/appcontnew.htm#JJDBC29073 You must use either the oracle.jdbc.replay.OracleDataSourceImpl or oracle.jdbc.replay.OracleConnectionPoolDataSourceImpl data source to obtain JDBC connections. They are new Oracle JDBC data sources, and work similarly to the existing non-XA data sources, such as oracle.jdbc.pool.OracleDataSource. You can use both in a standalone manner, or configure them as connection factories for a connection pool, such as Universal Connection Pool (UCP), or Oracle WebLogic Server connection pool.
  • #26 [1] « In collaboration with the database, the JDBC replay driver maintains a history of calls during a conversation between a client and the database. For each call made at run time, the driver retains the context required for a subsequent replay. » https://docs.oracle.com/database/121/CNCPT/transact.htm#CNCPT-GUID-2E973242-2B39-42FC-AA16-CD97B460B6D2
  • #32 [1] On the demo app O*Trade : With the replay-driver With the non-replay driver After killing the session, the same session get re-created : with the same ID (cf image below) However in Swingbench, the couple SID and serial # is different after the replay After killing the session, when you close the cursor and clidk Query again, the session ID is different..
  • #34 [1] « In collaboration with the database, the JDBC replay driver maintains a history of calls during a conversation between a client and the database. For each call made at run time, the driver retains the context required for a subsequent replay. » https://docs.oracle.com/database/121/CNCPT/transact.htm#CNCPT-GUID-2E973242-2B39-42FC-AA16-CD97B460B6D2