Home

Multiple Databases

You may access multiple databases in an application, using PriDE’s concept of a database context. As long as you don’t explicitly address particular contexts, you are implicitly working with a default context. If you recall the chapter about resource accessors and the the application bootstrap, there appeared two calls which initialized the default context:

DatabaseFactory.setDatabaseName(...)
DatabaseFactory.setResourceAccessor(...);

If you want to work with multiple databases, you have to initialize multiple contexts in the bootstrap in the same manner. The contexts are addressed by name and you perform a context switch by calling the DatabaseFactory’s static method setContext(). Switching to a context which doesn’t yet exist, causes the context to be created.

// Initialize the default database context
DatabaseFactory.setDatabaseName(...)
DatabaseFactory.setResourceAccessor(...);

// Create a new context by switching
DatabaseFactory.setContext("other-db");

// Initialize the new context
DatabaseFactory.setDatabaseName(...)
DatabaseFactory.setResourceAccessor(...);

// Switch back to the default context
DatabaseFactory.setContext(DatabaseFactory.DEFAULT_CONTEXT);

Alternatively you can add a context without switching back and forth by calling method addContext().

There are two ways how to work with these contexts:

Multi-Database Transactions

Although SQL database usually provide very good transaction safety for their own, the transaction management across multiple independent databases is a separate challenge. If your are working in a JEE environment, the application server should provide a safe transaction coordination for the involved databases, e.g. a 2 phase commit protocol. In a JSE environment you either have to integration a transaction manager like Atomikos or follow design patterns that minimize the risk of data inconsistencies.

A recommended design pattern is the so-called best efforts 1 phase commit. If you have to perform modifications in multiple databases within one transaction then do the actual work in all involved databases first and at the very end, run the commit calls for all databases. I.e. inconsistencies can only occur if any of the commit calls should fail which is a very rare situation. The pattern is suitable not only for databases but can be applied to any combined usage of transactional resources. In that case you should start the sequence of commit calls with the resource with the highest failure risk. E.g. you may assume that committing a JMS queue or a Kafka topic has a higher failure risk than committing a transaction on an Oracle database server based on decades of experience and hardening.