JBoss Datasource HA configuration made simple

JBoss / WildFly Datasource High availability was a feature available in older JBoss AS versions (namely JBoss AS 4 and 5).

The current version of the application server still allows to use some HA strategies, although the best practice to implement HA at Database level, by clustering your Database. Clustering the Database refers to the ability of several servers or instances to connect to a single database endpoint.

Configuring MultiDatasources in WildFly / JBoss EAP

When configuring the connection-url parameter of the data source element, it’s possible to specify a set of JDBC URLs. This is the multi data source feature. You need to specify the list of connection urls and a delimiter to separate them. Example:

/subsystem=datasources/data-source=PostgrePool/:write-attribute(name=connection-url,value=jdbc:postgresql://172.17.0.2/postgres| jdbc:postgresql://172.17.0.3/postgres )

/subsystem=datasources/data-source=PostgrePool/:write-attribute(name=url-delimiter,value=|)

For a production environment, it’s however recommended to use a more robust approach such as Oracle Real Application Cluster (RAC), which allows data high availability. In the following example, we are using a connection-url, which features an Oracle RAC made up of two nodes (host1 and host2):

/subsystem=datasources/data-source=OracleDS/:write-attribute(name=connection-url,value=jdbc:oracle:thin:@(description=(address_list=(load_balance=on)(failover=on)(address=(protocol=tcp)(host=host1)(port=1521))(address=(protocol=tcp)(host=host2)(port=1521)))(connect_data=(service_name=sid)(failover_mode=(type=select)(method=basic)))))

JBoss AS 4 HA Datasources

In JBoss AS 4, A High availability data source is an abstraction around a group of data sources that provides failover processing between a list of data source. High availability data sources are bound to the JNDI tree or local application context just like data sources are bound to the JNDI tree.

When you configure an HA Datasource you can choose a list of Connection URL- when the Connection you are using is not available anymore, the connection factory will (transparently to the user) choose another database connection URL, try to allocate a connection using it and, in case of success, return the connection back to the user.

jboss HA Datasource

Configuring an HA Datasource is a matter of a few steps:

1. Check that resource adapters are deployed

In order to use HA Datasource you need a specialized version of the Connection factory: depending if you use local or XA transaction you would need the files jboss-ha-local-jdbc.rar and jboss-ha-xa-jdbc.rar packages.

jboss datasource

In recent versions of JBoss this files are already deployed under the “default” configuration. In older release you can find the Resource Adapters under JBOSS_HOME/docs/examples/jca

2. Create the DataSource Configuration file

The configuration file for an HA datasource isnot much different from an ordinary datasource file, what makes the trick is the “<url-delimiter>” which separates the list of Connection-urls.
So here’s a configuration for a Local HA Datasource with an Oracle driver class:

<?xml version="1.0" encoding="UTF-8"?>   
<datasources>    
 <ha-local-tx-datasource>      
  <jndi-name>HADefaultDS</jndi-name>      
   <!-- list of connection URLs -->      
   <connection-url>jdbc:oracle:thin:@oraclehost:1521:SID|jdbc:oracle:thin:@oraclehost:1521:SID2       
   </connection-url>       
   <url-delimiter>|</url-delimiter>      
   <!-- The driver class -->      
   <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>      
   <user-name>user</user-name>      
   <password>password</password>       
   <!-- this will be run before a managed connection is removed from the pool for use by a client-->     
   <check-valid-connection-sql>select count(*) from testable</check-valid-connection-sql>   
 </ha-local-tx-datasource>  
</datasources>

If on the other hand you need to configure an XA HA Datasource, you can use the following template:

<ha-xa-datasource>       
 <jndi-name>XaHADefaultDS</jndi-name>        
 <!-- This disables transaction interleaving (which BTW,most DB vendors don't support) -->       <track-connection-by-tx></track-connection-by-tx>       
 <isSameRM-override-value>false</isSameRM-override-value>       
 <xa-datasource-class>org.jboss.test.jca.adapter.MockedXADataSource</xa-datasource-class>       
 <!-- list of connection URLs -->       
 <xa-datasource-property name="URL">jdbc:oracle:thin:@oraclehost:1521:SID|jdbc:oracle:thin:@oraclehost:1521:SID2</xa-datasource-property>       
 <url-property>URL</url-property>       
 <url-delimeter>|</url-delimeter>       
 <check-valid-connection-sql>VALUES CURRENT TIMESTAMP</check-valid-connection-sql>    
</ha-xa-datasource>

What happens if one connection fails ?

When a Connection is no longer available JBoss warns you about it and picks up the next Connection from the list using the Round-Robin Algorithm.

15:20:01,234 WARN  [HALocalManagedConnectionFactory] Failed to create connection  for jdbc:oracle:thin:@oraclehost:1521:SID: IO Exception : The Network Adapter could not establish the connection

JBoss 5 High Availability Datasource

JBoss 5 has changed the configuration for HA Datasources. You don’t have anymore
<ha-local-tx-datasource> or  <ha-xa-datasource> Element. Simply use a Connection URL with a list of Connections separated by an URL Delimiter.
Here’s an example for an XA-Datasource:

<datasources>
  <ha-local-tx-datasource>
  
    <jndi-name>jdbc/DBConnection</jndi-name>
    <connection-url>jdbc:oracle:thin:@host1:1521:db1|jdbc:oracle:thin:@host2:1521:db2</connection-url>
    <url-delimiter>|</url-delimiter>

    <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
    <user-name>scott</user-name>
    <password>tiger</password>

    
    <min-pool-size>5</min-pool-size>
    <max-pool-size>20</max-pool-size>

    <check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>

    <valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</valid-connection-checker-class-name>

    <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>

    
  </ha-local-tx-datasource>

</datasources>

Also, in the new Application Server release you don’t have any more jboss-ha-local-jdbc.rar and jboss-ha-xa-jdbc.rar.

The logic contained in Classes HALocalManagedConnectionFactory and  HAXAManagedConnectionFactory has been transferred directly in the standard XA/Local ManagedConnectionFactory