Skip to content

JDBC와 Failover

JDBC and Failover#

This section explains how to use the Failover feature in an Altibase JDBC application.

What is a Failover?#

When a failure occurs on the database server and the connection is disconnected, a Failover is a feature which enables the application to immediately establish a connection to another server to continue the execution of the previously executed operation.

Failover can operate in the following two ways:

CTF(Connection Time Failover)#

CTF attempts to connect to another server when an attempt to connect to the database is unsuccessful. CTF can occur when the connect method of a Connection object is called.

STF(Session Time Failover)#

STF connects to another server and continuously executes the user-specified operation when a connection error occurs before the result of a SQL statement is received from the server. STF can occur on the execution of all methods communicating with the server, excluding the connect method.

For more detailed information on Failover, please refer to the "Failover" chapter of Replication Manual.

How to Use Failover#

This section explains how to use the CTF and STF features in JDBC applications.

CTF#

The CTF feature can be used by adding the following properties to the Properties object.

Properties sProps = new Properties();
sProps.put("alternateservers", "(database1:20300, database2:20300)");
sProps.put("connectionretrycount", "5");
sProps.put("connectionretrydelay", "2");
sProps.put("sessionfailover", "off");

For more detailed information on each of the properties, please refer to "Connection Information" of Chapter 1.

STF#

The STF feature can be used by additionally setting "SessionFailover=on" to the properties which set the CTF feature.

In communication situations other than attempting to establish connection to the database server, the client first processes CTF and restores the connection when it detects server failure. Thereafter, the client executes the callback function registered by the user and raises a Failover Success Exception for the user to acknowledge that a Failover has occurred. If Failover fails to every server, the driver throws the Exception which originally occurred.

The following is an interface for the Failover callback function written by the user.

public interface AltibaseFailoverCallback
{
    public final static class Event
    {
        public static final int BEGIN     = 0;
        public static final int COMPLETED = 1;
        public static final int ABORT     = 2;
    }
    public final static class Result
    {
        public static final int GO   = 3;
        public static final int QUIT = 4;
    }
    int failoverCallback(Connection aConnection,
                         Object     aAppContext,
                         int        aFailoverEvent);
};

The following is a code example which shows the process of a user registering and freeing a Failover callback function.

public class  UserDefinedFailoverCallback implements AltibaseFailoverCallback
{
    ...

    public int failoverCallback(Connection aConnection,
                                Object     aAppContext,
                                int        aFailoverEvent)
    {
        // User Defined Code
        // Must return either Result.GO or Result.QUIT.
    }

    ...
}

If the Failover callback function written by the user is called by the JDBC driver, one of the Event constants included in the above AltibaseFailoverCallback interface is passed to aFailoverEvent, which is the third argument of the callback function. The meaning of each Event constant is as follows:

  • Event.BEGIN: Session Failover is started

  • Event.COMPLETED: Session Failover has succeeded

  • Event.ABORT: Session Failover has failed

The Result constants included in the AltibaseFailoverCallback interface are values which can be returned by the callback function written by the user. If values other than Result constants are returned from the callback function, Failover does not operate normally.

  • Result.GO If this constant value is returned from the callback function, the JDBC driver continually runs the next process of STF.
  • Result.QUIT If this constant value is returned from the callback function, the JDBC driver terminates the STF process.

The following is a code example of an object which can be used as the second argument of the Failover callback function written by the user.

public class UserDefinedAppContext
{
    // User Defined Code
}

If there is a need to use information of an application implemented by the user during the STF process, the object to be passed to the callback function while registering the Failover callback function can be specified. If this object is specified as the second argument of the registerFailoverCallback method which registers the callback function, this object is passed when the callback function is actually called. The following is an example which depicts this process in code.

// Create a user-defined callback function object.
UserDefinedFailoverCallback sCallback = new UserDefinedFailoverCallback();
// Create a user-defined application information object
UserDefinedAppContext sAppContext = new UserDefinedAppContext();

...

Connection sCon = DriverManager.getConnection(sURL, sProp);
// Register the callback function with the user-defined application object
((AltibaseConnection)sCon).registerFailoverCallback(sCallback, sAppContext);

...

// Free the callback function
((AltibaseConnection)sCon).deregisterFailoverCallback();

Code Example#

This is a code example which implements a callback function for STF.

The following is an example of a simple code which is regardless of various circumstances; therefore, it should be noted that it cannot be used as it is in user applications.

public class MyFailoverCallback implements AltibaseFailoverCallback
{
    public int failoverCallback(Connection aConnection, Object aAppContext,int aFailoverEvent)
    {
        Statement sStmt = null;
        ResultSet sRes = null;

        switch (aFailoverEvent)
        {
            // Necessary operations before starting Failover on the user application logic can be executed.
 case Event.BEGIN:
                System.out.println("Failover Started .... ");
                break;
            // Necessary operations after completing Failover on the user application logic can be executed.
 case Event.COMPLETED:
                try
                {
                    sStmt = aConnection.createStatement();
                }
                catch( SQLException ex1 )
                {
                    try
                    {
                        sStmt.close();
                    }
                    catch( SQLException ex3 )
                    {
                    }
                    return Result.QUIT;
                }

                try
                {
                    sRes = sStmt.executeQuery("select 1 from dual");
                    while(sRes.next())
                    {
                        if(sRes.getInt(1) == 1 )
                        {
                            break;
                        }
                    }
                }
                catch ( SQLException ex2 )
                {
                    try
                    {
                        sStmt.close();
                    }
                    catch( SQLException ex3 )
                    {
                    }
                    // Terminates the Failover process.
                    return Result.QUIT;
                }
                break;
        }
        // Continues the Failover process.
        return Result.GO;
    }
}

The following is a code example which checks whether or not STF was successful. Whether STF succeeded or failed can be confirmed by checking whether ErrorCode of SQLException is identical to Validation.FAILOVER_SUCCESS. The Failover validation code is inserted inside the while loop because the operation which was previously under execution must be executed again, even if Failover succeeds.

// Must be implemented so that the operation to be executed can be re-executed..
// The while loop has been used in this case.
while (true)
{
    try
    {
        sStmt = sConn.createStatement();
        sRes = sStmt.executeQuery("SELECT C1 FROM T1");
        while (sRes.next())
        {
            System.out.println("VALUE : " + sRes.getString(1));
        }
    }
    catch (SQLException e)
    {
        // Whether or not the Failover has succeeded.
        if (e.getErrorCode() == AltibaseFailoverCallback.FailoverValidation.FAILOVER_SUCCESS)
        {
            // Since Failover has succeeded, Exception is ignored and the process is continued. continue;
        }
        System.out.println("EXCEPTION : " + e.getMessage());
    }
    break;
}