Overview
Transparent Application Failover (TAF) is a feature of the Java Database Connectivity (JDBC) Oracle Call Interface (OCI) driver. It enables the application to automatically reconnect to a database, if the database instance to which the connection is made fails. In this case, the active transactions roll back.
When an instance to which a connection is established fails or is shutdown, the connection on the client side becomes stale and would throw exceptions to the caller trying to use it. TAF enables the application to transparently reconnect to a preconfigured secondary instance creating a fresh connection, but identical to the connection that was established on the first original instance. That is, the connection properties are the same as that of the earlier connection. This is true regardless of how the connection was lost.
Notes:
TAF is always active and does not have to be set.TAF only works for idle sessions and SELECT statements.
The following are possible failover events in the OracleOCIFailover
interface:
FO_SESSION
FAILOVER_MODE=SESSION
in the tnsnames.ora
file CONNECT_DATA
flags. This means that only the user session is authenticated again on the server-side, while open cursors in the OCI application need to be reprocessed.FO_SELECT
FAILOVER_MODE=SELECT
in tnsnames.ora
file CONNECT_DATA
flags. This means that not only the user session is re-authenticated on the server-side, but open cursors in the OCI can continue fetching. This implies that the client-side logic maintains fetch-state of each open cursor.FO_NONE
FAILOVER_MODE=NONE
in the tnsnames.ora
file CONNECT_DATA
flags. This is the default, in which no failover functionality is used. This can also be explicitly specified to prevent failover from happening. Additionally, FO_TYPE_UNKNOWN
implies that a bad failover type was returned from the OCI driver.FO_BEGIN
FO_END
FO_ABORT
FO_REAUTH
FO_ERROR
sleep
method and retry by returning the value FO_RETRY
.FO_RETRY
FO_EVENT_UNKNOWN
TAF callbacks are used in the event of the failure of one database connection, and failover to another database connection. TAF callbacks are callbacks that are registered in case of failover. The callback is called during the failover to notify the JDBC application of events generated. The application also has some control of failover.
Note:
The callback setting is optional.
The OracleOCIFailover
interface includes the callbackFn
method, supporting the following types and events:
public interface OracleOCIFailover{
// Possible Failover Types
public static final int FO_SESSION = 1;
public static final int FO_SELECT = 2;
public static final int FO_NONE = 3;
public static final int;
// Possible Failover events registered with callback
public static final int FO_BEGIN = 1;
public static final int FO_END = 2;
public static final int FO_ABORT = 3;
public static final int FO_REAUTH = 4;
public static final int FO_ERROR = 5;
public static final int FO_RETRY = 6;
public static final int FO_EVENT_UNKNOWN = 7;
public int callbackFn (Connection conn,
Object ctxt, // ANy thing the user wants to save
int type, // One of the possible Failover Types
int event ); // One of the possible Failover Events
Handling the FO_ERROR Event
In case of an error while failing-over to a new connection, the JDBC application is able to retry failover. Typically, the application sleeps for a while and then it retries, either indefinitely or for a limited amount of time, by having the callback return FO_RETRY
.
Handling the FO_ABORT Event
Callback registered should return the FO_ABORT
event if the FO_ERROR
event is passed to it.
Sample tnsnames.ora entries to configure TAF:
sales =
(DESCRIPTION =
(ENABLE=BROKEN)
(LOAD_BALANCE=yes)
(ADDRESS=(PROTOCOL=TCP)(HOST=node1)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=node2)(PORT=1521))
(CONNECT_DATA=
(SERVICE_NAME=sales)
(FAILOVER_MODE =
(TYPE=session)
(METHOD=basic)
(RETRIES=10)
(DELAY=10)
)
)
)
Non-TAF entries to connect directly to specific instances:
node1_sales =
(DESCRIPTION =
(ADDRESS=(PROTOCOL=TCP)(HOST=node1)(PORT=1521))
(CONNECT_DATA =
(SERVICE_NAME=sales)
(INSTANCE_NAME=sales1)
)
)
node2_sales =
(DESCRIPTION =
(ADDRESS=(PROTOCOL=TCP)(HOST=node2)(PORT=1521))
(CONNECT_DATA =
(SERVICE_NAME=sales)
(INSTANCE_NAME=sales2)
)
)