Skip to end of metadata
Go to start of metadata


This wiki will go through a closer look into how HADR will affect your client applications. We will not go into detail on HADR for SAP ASE, but will go through ODBC, jConnect, and Open Client (CT-Library). 


The always-on option is a high-availability and disaster recovery (HADR) system with two ASE servers which work together to make sure your enterprise never fails.  One of the ASE servers is the 'Primary' server and the other is a 'Standby' server.  In the HADR setup, the Primary ASE will be the one actively processing and fulfilling client requests.  The Primary ASE will replicate to the Standby ASE making sure it is up-to-date encase of any disaster, upgrade, or downtime.  When a disaster occurs the Fault Manager will detect that the Primary ASE is no longer available.  The Fault Manger will then promote the Standby server to Primary server; essentially switching Primary and Standby servers.  Once the old Primary server is back online it will be informed it is the new Standby server.  The new Primary server will replicate any new data or changes to the new Standby server.

Note: RMA and SAPHostAgent is a part of the Replication.  Also, Cockpit is a monitoring tool that comes with ASE installations that can be setup to manage ASE servers. 

HADR Redirect

When you enable HADR, this will automatically enable the redirect property. When the redirect property is enabled it will check the ASE server to see if it the Primary or Standby ASE.  When a client connects to the Standby ASE server as a non-admin, the connection will be redirected to the Primary ASE server.  This helps prevent data inconsistencies and allows the clients to always connect to the Primary server.  If you need to connect to the Standby ASE server you can use an admin user such as sa to connect.

Coding HADR applications

All the clients will receive an informational message that says HADR failover is occurring.  This means when the client application receives this message it needs to somehow rerun the command or remember where it left off and continue.  This will require new code to allow the application to successfully failover.

jConnect / JDBC

There are a few connection properties used to enable HADR in a jConnect application:

  • HADR_MODE = NONE (Default Value)
    • HADR feature won’t be support to client application
    • jConnect requests ASE to send HADR address list during login time
      Address list is also send asynchronously if there is change in server side topology
      Client application can determine primary/secondary server from HADR list map send by server
      HADR list map is always send by primary server
    • jConnect requests ASE not to terminate existing connection until current primary is deactivated and new primary active server is seen in topology
      No new transaction will be allowed if server is in deactivating/deactivated state
    • Its a combination of both MAP and NOKILL property
      During login time HADR address list is send, or when there is change is topology server asynchronously send list information
      Connection won’t get terminated until current primary is deactivated and new primary active server is seen in topology
      No new transaction will be allowed if server is in deactivating/deactivated state
    • jConnect will internally set connection property
    • Whenever primary server is deactivated and standby server is made primary active, jConnect will re-establish connection to newly activated primary connection will be re-established only when client tries to perform some activity Upon re-establishment of connection to new primary, client application will receive SQLException as: “JZ0F2: SAP Adaptive Server Enterprise high-availability failover has occurred. The current transaction is aborted, but the connection is still usable“
    • It would be client application’s responsibility to catch above sql exception and recreate/reset all context object such as statement, prepared statement, callable statement etc.
    • Note: Whenever HADR_MODE = RECONNECT property is used, client application should also ideally set connection property SECONDARY_SERVER_HOSTPORT. If client ries to connect server which down and SECONDARY_SERVER_HOSTPORT value is not set then application will get SQLException as:“JZ0F1: SAP Adaptive Server Enterprise high-availability failover connection was requested but the companion server address is missing”

jConnect can request and be aware of the HADR state.
Here are the possible states:

  • NONE
    • indicates that the HADR server does not support the HADR feature or the client has set connection property HADR_MODE=NONE/null
    • indicates that the current connection is to the active primary server and the client can perform any operation
    • indicates that the server is undergoing deactivation and the client application must not perform any new operation using the current connection
    • If connection property is HADR_MODE=RECONNECT/NOKILL/NOKILL_WITH_MAP, then the active transactions can be extended
    • No new transaction can be started in DEACTIVATING state. If client tries to perform any new operation a SQLException is thrown with error code:2377
    • indicates that the server was successfully deactivated and no new operation can be performed using the current connection.
    • If connection property is HADR_MODE=RECONNECT/NOKILL/ NOKILL_WITH_MAP, then the connections are intact but are not usable.
    • If the client tries to execute any query a SQLException is thrown with error code: 2379
    • If connection property is HADR_MODE=MAP/NONE, and the client tries to perform operations in this state then the connection is terminated
    • indicates that the server deactivation was canceled and current connection object is reusable
    • indicates that a deactivated server is reactivated, hence the current connection object is reusable. This state is seen only when the connection property is HADR_MODE=RECONNECT/NOKILL/ NOKILL_WITH_MAP
    • indicates that the connection to the old active primary server is killed, and the client is now connected to the new active primary server
    • During failover, if the client tries to execute a query, the following message displays: JZ0F2 - SAP Adaptive Server Enterprise high-availability failover has occurred
    • The current transaction is aborted, but the connection is still usable
    • The client application must re-create/reset all context objects, such as statements, prepared statements, callable statements, and so on
    • The FAILOVER state appears only when the connection property is set to HADR_MODE=RECONNECT

When configuring a java application to use HADR, you will need to update the connectionstring to add HADR_MODE=RECONNECT.  Once this is set the application will be ready to use any new HADR setting or properties.  This will also enable the ASE to send needed information to the client. 

For Primary and Secondary server information you can use conn.getClientInfo() to gather information on each ASE server:
Properties hadrProps = connPrimary.getClientInfo();
HashMap hadrMap = (HashMap)hadrProps.get("HADR_LISTMAP");

You can also use getClientInfo to generate the current state of HADR
At the end of this section is a sample application that you can test in your environment.

The next part would be to modify the application to pick up that a HADR failover has occurred.  This is done through the sql exception JZ0F2. Creating a try catch can help gather the exception and proceed as needed..

Here is a sample jConnect application for testing purposes:

Application output:
C:\SAP\jConnect-16_0\sample2>java Test
Group Name: ha1_group
Generation Number: 0
DSN Type: Primary
DSN Name: ha1_ASE1
Address List: tcp ASEhost1 ASEport1
HA Failover List:
Flag: 0

DSN Type: Standby_1
DSN Name: ha1_ASE2
Address List: tcp ASEhost2 ASEport2
HA Failover List:
Flag: 0 

sleeping for 10 seconds
Current Server state: ACTIVE
Error Message: JZ0F2: SAP Adaptive Server Enterprise high-availability failover has occurred. The current transaction is aborted, but the connection is still usable. Retry your transaction.
Row: 1
au_id: 172-32-1176
last name: rubini
first name: Johnson
phone: 408 496-7223
address: 10932 Bigge Rd.
city: Menlo Park
state: CA
country: USA
postalcode: 94025

Row: 2

Open Client (CT-Library)

Open Client has 3 ct_con_props that can be set when using HADR:

    • Enabled by default if CS_HAFAILOVER is enabled
    • CS_PROP_REDIRECT is the property that will redirect clients to the Primary ASE if they attempt to connect to the standby ASE server.
    • This redirection only occurs to non-admin logins
    • This property cannot be set to false unless CS_HAFAILOVER is set to false.
    • Disabled by default
    • When enabled this allows HADR support to the application. 
    • This will enable CS_PROP_REDIRECT and CS_PROP_EXTENDEDFAILOVER by default.
    • Enabled by default if CS_HAFAILOVER is enabled
    • This property allows the client to receive the network address information to the Primary and Standby ASE servers.
    • If this property is set to false than any connection or login will use directory service, interfaces, or sql.ini. 

The only property that you need to add to your connection is CS_HAFAILOVER.  This property will enable all needed properties when set.  Once you’re application is hadr ready, you will need to catch the error CS_RET_HAFAILOVER.  This is what will be sent to the client when a failover occurs.  When you capture CS_RET_HAFAILOVER, you will need to re-execute the last query or restart the transaction.  The attached code is sample firstapp.c modified for hadr support.  In CS_RET_HAFAILOVER I just added the previously executed code so the command will be re-executed:

* ** We've finished processing results. Check the return value of
*** ct_results() to see if everything went okay.
switch ((int)results_ret)
/*ha failover */
printf("Resending the cmd\n");
ret = ct_cmd_alloc(connection, &cmd);
EXIT_ON_FAIL(context, ret, "ct_cmd_alloc() failed");
ret = ct_command(cmd, CS_LANG_CMD,
"select au_lname, city from pubs2..authors \
where state = 'CA'",
EXIT_ON_FAIL(context, ret, "ct_command() failed");
ret = ct_send(cmd);
       EXIT_ON_FAIL(context, ret, "ct_send() failed");

Modified firstapp.c sample:

Application output:
Server message:
       number(5701) severity(10) state(2) line(0)
       Server name: hadr2
       Changed database context to 'master'.
Client Library error:
       severity(0) number(201) origin(2) layer(1)
       ct_results(): user api layer: internal Client Library error: HAFAILOVER:Trying to connect to hadr2 server.
Server message:
      number(5701) severity(10) state(2) line(0)
       Server name: hadr1
       Changed database context to 'master'.
Resending the cmd
rubini: Menlo Park
Green: Oakland
Carson: Berkeley
O'Leary: San Jose
Straight: Oakland
Bennet: Berkeley
Dull: Palo Alto
Gringlesby: Covelo
Locksley: San Francisco
Yokomoto: Walnut Creek
Stringer: Oakland
MacFeather: Oakland
Karsen: Oakland
All done processing rows.


Here are the connectionstring properties that can be enabled for HADR:

  • HADRList
    • Default value is 0
    • When enabled this will request the network address for both Primary and Standby ASE servers.
    • This will also send the status of each server and a generation number so that you know the data you have is up-to-date or has been modified.
    • An example of this is in the sample application attached.
  • DRNoKillDuringDeactivation
    • Default value is 0
    • When enabled it sets hadr_gentle_cap capability on ASE which refrains ASE from terminating the connection while the primary is inactive or undergoing deactivation
    • Any attempt to start new transactions while deactivation is in progress result in errors.
    • When set, ASE sends asynchronous messages(events), which can be fetched using ODBC API
    • NoKill connections are killed upon activation of new primary ASE, it allows client application to know exactly when to connect to new primary rather than keep attempting to connect until successful.
  • EnableRedirect
    • Default value is 1
    • This property will redirect the application to the Primary ASE server when attempting to connect to the Standby ASE.
    • This redirection only occurs to non-admin logins
  • HASession
    • Default value is 0
    • When set, it turns on the high availability feature in ODBC driver
    • This ensures smooth transition of user connections to new active primary in case of planned and unplanned failover events
    • Failover in HADR system does not migrate the context, instead applications are notified about failover events and they need to reestablish the user context after successful failover
    • Application doesn’t need reconnection logic as it is handled internally by ODBC driver
  • HADRPrimaryWaitTime
    • Default value is 300 seconds
    • This property sets the time-out value for the ODBC driver to search for a new primary server in the event of an unplanned failover.
    • The value of the HADRPrimaryWaitTime connection property is always the same as that of the HADR primary wait time server configuration option.
  • HADRLoginStallTime –
    • Default value is 2 seconds
    • This property sets the time for the ODBC driver to stall the HADR login of the application in the event of an unplanned failover.
    • The value of the HADRLoginStallTime connection property is always the same as that of the HADR login stall time server configuration option.
  • HADRPrimaryCheckFrequency
    • Default value is 10 seconds
    • This property sets the frequency of the ODBC driver to check for the primary server in the event of an unplanned failover.
    • The value of the HADRPrimaryCheckFrequency connection property is always the same as that of the HADR login stall time server configuration option.
  • HADRMode
    • Default value is 0
    • This option makes it easier to enable HADR in odbc.
    • This property enables HASession, EnableRedirect, and DRNoKillDuringDeactivation
    • HADR aware applications can make use of asynchronous events to know what is the current state of HADR system and act accordingly
    • It provides more control over the HADR server state transition

 ODBC can request and be aware of the HADR state.
Here are the possible states:

  • SQL_DR_ACTIVATED – indicates server is in ‘active’ state
  • SQL_DR_DEACTIVATED – indicates server is ‘inactive’ and user should wait for failover or reactivation to happen
  • SQL_DR_DEACTIVATION_CANCELLED – indicates that deactivation process has cancelled and server is back in active state
  • SQL_DR_DEACTIVATING – indicates that the deactivation is in progress and application  needs to wait for failover to happen or deactivation to get cancelled
  • SQL_DR_FAILOVER – indicates that failover has happened
  • SQL_DR_CONNECTION_LOST – indicates that the connection to the primary server has lost because of planned or unplanned failover events

When enabling HADRMode=1 this will enable your ODBC application for HADR support.  Once this is done you can use SQLSetConnectAttr and SQLGetConnectAttr to receive the state.
This will then be used to capture if a failover is occurring and to re-execute the command.

 if (connection_state == SQL_DR_CONNECTION_LOST)
                   cout << "connection to primary is lost,  or primary went down, executing sql which will complete failover when new active primary is found" << endl;
                   /*execute a query, driver will keep going back and forth between standby and primary until it finds new primary or timeout of 5 minutes(configurable value on client and serve side -
HADR primary wait time').
                   If it finds the new primary then that will complete the failover in the driver.
                   The code below fetches the error stream and looks for failover error 30130 and sets the app context.
                   If it does not find new primary the failover will fail and control will return out of this function*/
                  sr = SQLExecute(stmt);

Here is the ODBC sample found in $SYBASE/DataAccess/ODBC/samples/hadrapp:

Application Output:
C:\SAP\DataAccess\ODBC\samples\hadrapp\Unicode Debug>hadrapp primaryASEhost primaryASEport standbyASEhost standbyASEport hadruser hadrpassword
--------ODBC HADR Fullblown feature set--------
Using connection string: Driver=Adaptive Server Enterprise;Server=primaryASEhost;Port=primaryASEport;UID=hadruser;PWD=hadrpassword;hadrmode=1;dynamicprepare=true;
author name updated
author name updated
--- paused when primary ASE goes down ---
--- continue execution when failover occurs and standby is switch to primary ---
author name updated
author name updated

Related Content

Related Documents 

SAP Adaptive Server Enterprise HADR Users Guide

Related sap notes/kbas 


  • No labels