ConfigJBossMQDB

Changing the database used by JBossMQ

 

By default JBossMQ uses hsqldb for persistence and caching. From 3.2.4 it also uses it

for saving durable topic subscriptions and authentication.

 

Do not use hypersonic in production

 

hsqldb is not a production quality database. It is suitable for demos and testing. JBoss ships with the database to help you get something working out of the box.

 

Known problems with hsqldb:

  • No transaction isolation

  • Thread and socket leaks - connection.close() does not tidy up resources

  • Persistence quality - the database is held in a file in the JBoss data directory, it is a common problem that log becomes corrupted after a failure, leaving you to manually edit the file to recover the database.

  • Stability under load - strange problems have been seen under load, including the database process "vanishing", i.e. it stops processing when too much data is sent, usually because of an OutOfMemory problem, but not necessarily.

  • hsqldb uses a file on the local server - although this can be changed to use a remote hsqldb instance, this negates many of the benefits of using hsqldb. The local file makes it impossible to use in a clustered environment.

 

Please go to the Don't use Hypersonic in production wiki for more information.

 

 

 

 

 

Approach 1: Easy, use "DefaultDS"

 

In this section we will be using "DefaultDS" as the jndi name for the datasource. Since all JBoss services using persistence are configured by default to use a datasource with jndi name "DefaultDs", the number of changes is reduced to a minimum.

 

 

 

Throughout the intructions we will be using an Oracle datasource as an

example.  You can find other example configurations for popular database systems in $JBOSS_HOME/docs/examples/jca and

$JBOSS_HOME/docs/examples/jms.

 

Installing the jdbc driver

 

 

JDBC drivers are provided in JAR archives by the database vendor or a third-party company.

 - Copy the jar file to server/[your server config]/lib

 

Deploying the datasource descriptor for your database

 

Datasource examples for the most popular databases are available in $JBOSS_HOME/docs/examples/jca.

 

 - Copy docs/examples/jca/oracle-ds.xml to deploy{-hasingleton}
 - Replace the <jndi-name> property value with "DefaultDS"
 - Configure the datasource (server url, user, password, etc...)
 - Remove deploy{-hasingleton}/hsqldb-ds.xml

 

 

Updating the Persistence Manager service

 

The persistence manager is using database-specific queries to create tables and other indexes.

Alternate persistence configurations can be found in $JBOSS_HOME/docs/examples/jms.

 

 - Copy docs/examples/jms/oracle-jdbc2-service.xml to deploy{-hasingleton}/jms
 - Remove deploy{-hasingleton}/hsqldb-jdbc2-service.xml

 

You may now restart the server instance.

 

 

 

 

 

Approach 2: Advanced, use your own datasource name

 

In this section, we describe the various changes required when the datasource's jndi name is NOT "DefaultDS".

 

 

Throughout the intructions we will be referencing an Oracle datasource named "OracleDS"

 

 

Installing the jdbc driver

 

 

JDBC drivers are provided in JAR archives by the database vendor or a third-party company.

 - Copy the jar file to server/[your server config]/lib

 

Deploying the datasource descriptor for your database

 

Datasource examples for the most popular databases are available in $JBOSS_HOME/docs/examples/jca.

 

 - Copy docs/examples/jca/oracle-ds.xml to deploy{-hasingleton}
 - Update the <jndi-name> property if needed
 - Configure the datasource (server url, user, password, etc...)
 - Remove deploy{-hasingleton}/hsqldb-ds.xml

 

Note: An XA datasource is not required for JBossMQ persistence. All work is done is separate transactions that only includes work on the JBossMQ tables. i.e. there is a single branch so there is no need for two phase commit.

 

Updating the Persistence Manager service

 

The persistence manager is using database-specific queries to create tables and other indexes.

Alternate persistence configurations can be found in $JBOSS_HOME/docs/examples/jms.

 

 - Copy docs/examples/jms/oracle-jdbc2-service.xml to deploy{-hasingleton}/jms
 - Remove deploy{-hasingleton}/hsqldb-jdbc2-service.xml

 

Updating the State Manager service (3.2.4+)

 

The state Manager holds durable subscriptions. You need to point the service at the correct datasource. In deploy{-hasingleton}/hsqldb-jdbc-state-service.xml

 

    <depends optional-attribute-name="ConnectionManager">jboss.jca:service=LocalTxCM,name=OracleDS</depends>

for JBoss4 this is

    <depends optional-attribute-name="ConnectionManager">jboss.jca:service=DataSourceBinding,name=OracleDS</depends>

 

You can also rename the config file to oracle-jdbc-state-service.xml if you like.

 

Changing the login config (3.2.4+)

 

Additionally the JBossMQ login config needs to be changed to use your chosen datasource. In

conf/login-config.xml update the module option dsJndiName.

 

    <!-- Security domain for JBossMQ -->
    <application-policy name = "jbossmq">
       <authentication>
          <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule"
             flag = "required">
             <module-option name = "unauthenticatedIdentity">guest</module-option>
             <module-option name = "dsJndiName">java:/OracleDS</module-option>
             <module-option name = "principalsQuery">SELECT PASSWD FROM JMS_USERS WHERE USERID=?</module-option>
             <module-option name = "rolesQuery">SELECT ROLEID, 'Roles' FROM JMS_ROLES WHERE USERID=?</module-option>
          </login-module>
       </authentication>
    </application-policy>

 

Note: If you get a JMSSecurity exception during the deployment, check out WhyDoIGetNullIsNOTAuthenticated

 

Updating the timer service

 

The Timer service is not used by JBossMQ although by removing any datasource with jndi name "DefaultDS" it will fail to deploy.

 

 

So in /deploy/ejb-deployer.xml, please update the optional attribute "Datasource" on the EJBTimerService MBean as follows:

 <!-- A persistence policy that persistes timers to a database -->
  <mbean code="org.jboss.ejb.txtimer.DatabasePersistencePolicy" name="jboss.ejb:service=EJBTimerService,persistencePolicy=database">
    <!-- DataSource JNDI name -->
    <depends optional-attribute-name="DataSource">jboss.jca:service=DataSourceBinding,name=OracleDS</depends>
    ...

 

Updating the HiLo generator service

 

The HiLo generator service is not used by JBossMQ although by removing any datasource with jndi name "DefaultDS" it will fail to deploy.

 

 

in /deploy/uuid-key-generator/META-INF, update the optional attribute "Datasource" on the KeyGeneratorFactory MBean as follows:

  <!-- HiLoKeyGeneratorFactory -->
  <mbean code="org.jboss.ejb.plugins.keygenerator.hilo.HiLoKeyGeneratorFactory"
         name="jboss:service=KeyGeneratorFactory,type=HiLo">
     <depends>jboss:service=TransactionManager</depends>
     <!-- Attributes common to HiLo factory instances -->
     <!-- DataSource JNDI name -->
     <depends optional-attribute-name="DataSource">jboss.jca:service=DataSourceBinding,name=OracleDS</depends>
     ....

 

Updating the juddi-service

 

The juddi service is not used by JBossMQ although by removing any datasource with jndi name "DefaultDS" it will fail to deploy.

 

 

Modify /deploy/juddi-service.sar/META-INF/jboss-service.xml to reflect new datasource name it depends on:

     ....
     <depends>jboss.jca:service=DataSourceBinding,name=OracleDS</depends>
     ....

 

 

 

Other considerations

 

 

The schema is not optimized!

 

As noted in the persistence configuration the schema created by JBoss is not optimized. You may want to create the schema by hand in the database. This will also include creating indexes. A commonly used access path is select ... from JMS_MESSAGES where TXID=? and TXOP=? so creating an index over TXID and TXOP improves performance.

 

Issues using MySQL and JBoss 4.0.3 / 4.0.3SP1

 

Using the example configuration for MySQL you may see the following error: -

 

org.jboss.mq.SpyJMSException: Could not resolve uncommited transactions. Message recovery may not be accurate; - nested throwable: (java.sql.SQLException: Every derived table must have its own alias)

 

Edit the persistence configuration and change the line :-

 

SELECT_MAX_TX = SELECT MAX(TXID) FROM (SELECT MAX(TXID) AS TXID FROM JMS_TRANSACTIONS UNION SELECT MAX(TXID) AS TXID FROM JMS_MESSAGES)

 

to: -

 

SELECT_MAX_TX = SELECT MAX(TXID) FROM JMS_MESSAGES

 

See http://jira.jboss.com/jira/browse/JBAS-2425

 

http://www.jboss.com/index.html?module=bb&op=viewtopic&p=39066723906672

 

 

Also using MySQL 4.1.10 this query was causing JBoss to hang for me, upgrading to MySQL 4.1.12 resolved this for me.

 

Issues using Postgres 8.1.3 and JBoss 4.0.3 / 4.0.3SP1

 

Using the example configuration for Postgres you may see the following error: -

 

org.postgresql.util.PSQLException: ERROR: subquery in FROM must have an alias

 

Edit the persistence configuration and change the line :-

 

SELECT_MAX_TX = SELECT MAX(TXID) FROM (SELECT MAX(TXID) AS TXID FROM JMS_TRANSACTIONS UNION SELECT M AX(TXID) AS TXID FROM JMS_MESSAGES)

 

to: -

 

SELECT_MAX_TX = SELECT MAX(TXID) FROM (SELECT MAX(TXID) AS TXID FROM JMS_TRANSACTIONS UNION SELECT M AX(TXID) AS TXID FROM JMS_MESSAGES) AS TXID

 

See http://jira.jboss.com/jira/browse/JBAS-2956

 

http://www.jboss.com/index.html?module=bb&op=viewtopic&t=79227

 

Issues using Postgres with JBoss 4.2.x

 

The /docs/examples/jms/postgres-jdbc2-service.xml differs from the standard deploy{-hasingleton}/hsqldb-jdbc2-service.xml. The jboss.mq:service=DestinationManager mbean has the following extra configuration in the hsql version:

    <depends optional-attribute-name="ThreadPool">jboss.mq:service=ThreadPool</depends>
    <depends>jboss:service=Naming</depends>

 

Without this configuration in the Postgres file, the number of JMSThread (the actual thread name) instances spawned by the application server is not managed. When this is added to the Postgres file, the application server will not spawn more threads than set in the ThreadPool configuration.