= Aries OSGi Transaction Control JDBC Provider (XA)

The Aries Local JDBC provider implementation is available at the following maven coordinates:

     <dependency>
         <groupId>org.apache.aries.tx-control</groupId>
         <artifactId>tx-control-provider-jdbc-xa</artifactId>
         <version>${aries.tx.control.version}</version>
     </dependency>

This module is a prototype implementation of the OSGi Transaction Control JDBC resource provider.
It supports both XA transactions and Local Transactions.
The provider also has built-in support for Database connection pooling using Hikari CP.

== When should I use this module?

If two-phase commit is needed across multiple resources then it is best to pair this module with  the tx-control-service-xa bundle.

If you wish to use entirely lightweight, resource-local transactions then then the  tx-control-service-local and tx-control-provider-jdbc-local bundles can be used instead.

== Quick Start

A configured JDBCConnectionProvider can be created quickly using Configuration Admin and the OSGi JDBC Service.

. Find and install a JDBC Service implementation for your chosen database (e.g.
the org.h2 bundle for H2)
. Create a factory configuration using the factory pid `org.apache.aries.tx.control.jdbc.xa`  and add the following properties:
 ** _osgi.jdbc.driver.class_ :- The driver class name (e.g.
org.h2.Driver)
 ** _url_ :- The JDBC URL to use to connect to the database

When the DataSourceFactory for the named `osgi.jdbc.driver.class` becomes available the Local JDBC Resource Provider will create a JDBCConnectionProvider and register it in the OSGi service registry.
All configuration properties (apart from the database password) will be registered as  properties of the JDBCConnectionProvider service.
These properties can be used to select a ResourceProvider if more than one is present in the Service Registry.

== Using the XA JDBC Provider bundle (details)

This Resource Provider is used in conjunction with a TransactionControl service to provide scoped  access to a JDBC connection with support for XA Transactions and Local Transactions.

When using XA transactions the XAResource from the Database provider is used to integrate with an ongoing XA transaction.
When using local transactions the JDBC API is used to commit or rollback the Database connection.

== Creating a resource programmatically

Preparing a resource for use is very simple.
Create a `JDBCConnectionProvider` using the  `JDBCConnectionProviderFactory` service from the service registry, then connect that  provider to a `TransactionControl` service.
This will return a thread-safe JDBC connection  that can then be used in any ongoing scoped work.
The JDBCConnectionProviderFactory service is registered with the `osgi.xa.enabled` property set to `true`.

The normal inputs to a JDBCConnectionProviderFactory are a DataSourceFactory, some JDBC  properties to connect to the database with, and some properties to control the resource provider  (such as connection pooling).

=== Declarative Services Example

....
@Component
public class TransactionalJDBCComponent {
    @Reference
    TransactionControl txControl;

    @Reference
    DataSourceFactory dsf;

    @Reference
    JDBCConnectionProviderFactory providerFactory;

    Connection conn;

    @Activate
    void start(Config config) {

        Properties jdbcProps = new Properties();
        jdbcProps.put(JDBC_URL, config.url());
        jdbcProps.put(JDBC_USER, config.user());
        jdbcProps.put(JDBC_PASSWORD, config._password());

        Map<String, Object> providerProps = new HashMap<>();
        providerProps.put(MAX_POOL_SIZE, 8);

        conn = providerFactory.getProviderFor(dsf,
        jdbcProps, providerProps).getResource(txControl);
    }

    public void findUserName(String id) {
        txControl.required(() -> {
                // Use the connection in here
            });
    }
}
....

If a JDBC DataSource/Driver is already configured then it can be passed in to the  JDBCConnectionProviderFactory instead of a DataSourceFactory and JDBC configuration.

== Creating a resource using a factory configuration

Whilst it is simple to use a `JDBCConnectionProviderFactory` it does require some  lifecycle code to be written.
It is therefore possible to directly create JDBC resources using factory  configurations.
When created, the factory service will listen for an applicable DataSourceFactory.
Once a suitable DataSourceFactory is available then a JDBCConnectionProvider service will be published.

Configuration properties (except the JDBC password) are set as service properties for the registered  `JDBCConnectionProvider`.
These properties may therefore be used in filters to select  a particular provider.

=== Declarative Services Example

....
@Component
public class TransactionalJDBCComponent {

    @Reference
    TransactionControl control;

    Connection conn;

    @Reference(target="(dataSourceName=myDataSource)")
    void setProvider(JDBCConnectionProvider provider) {
         conn = provider.getResource(control);
    }

    public void findUserName(String id) {
        control.required(() -> {
                // Use the connection in here
            });
    }
}
....

The factory pid is _org.apache.aries.tx.control.jdbc.xa_ and it may use the following properties (all optional):

=== Resource Provider properties

* _aries.dsf.target.filter_ : The target filter to use when searching for a DataSourceFactory.
If not specified then _osgi.jdbc.driver.class_ must be specified.
* _aries.jdbc.property.names_ : The names of the properties to pass to the DataSourceFactory when creating the JDBC resources
* _osgi.jdbc.driver.class_ : Used to locate the DataSourceFactory service if the _aries.dsf.target.filter_ is not set.
* _osgi.local.enabled_ : Defaults to true.
If false then this resource will not participate in local transactions, and will fail if used within one.
One of _osgi.local.enabled_ and _osgi.xa.enabled_ must be true.
* _osgi.xa.enabled_ : Defaults to true.
If false then this resource will not participate in xa transactions, and will fail if used within one.
One of _osgi.local.enabled_ and _osgi.xa.enabled_ must be true.
* _osgi.connection.pooling.enabled_ : Defaults to true.
If true then the Database connections will be pooled.
* _osgi.connection.max_ : Defaults to 10.
The maximum number of connections that should be kept in the pool
* _osgi.connection.min_ : Defaults to 10.
The minimum number of connections that should be kept in the pool
* _osgi.connection.timeout_ : Defaults to 30,000 (30 seconds).
The maximum time in milliseconds to block when waiting for a database connection
* _osgi.idle.timeout_ : Defaults to 180,000 (3 minutes).
The time in milliseconds before an idle connection is eligible to be closed.
* _osgi.connection.timeout_ : Defaults to 10,800,000 (3 hours).
The maximum time in milliseconds that a connection may remain open before being closed.
* _osgi.use.driver_ : Defaults to false.
If true then use the createDriver method to connect to the database.
Cannot be true if _osgi.xa.enabled_ is true.

=== JDBC properties

The following properties will automatically be passed to the DataSourceFactory if they are present.
The list of properties may be overridden using the _aries.jdbc.property.names_ property if necessary.

* _databaseName_ : The name of the database
* _dataSourceName_ : The name of the dataSource that will be created
* _description_ : A description of the dataSource being created
* _networkProtocol_ : The network protocol to use.
* _portNumber_ : The port number to use
* _roleName_ : The name of the JDBC role
* _serverName_ : The name of the database server
* _url_ : The JDBC url to use (often used instead of other properties such as _serverName_, _portNumber_ and _databaseName_).
* _user_ : The JDBC user
* _password_ : The JDBC password
