Version 1

    Issue Metadata

    * EAP issue:

    * Dev Contacts: Francesco Nigro, Artemis

    * Affected projects or components: Artemis


    Design Details


    The JDBC Shared Store functionality is activated when the broker is configured with a database store type and it behaves 1:1 as the FileLock based one: it uses a shared state (not a file, but a database table) to guarantee live and backups to coordinate actions against a shared store (the JDBC journal instead of the file based one).


    The main difference with the file based shared store is how the live and backups locks are implemented: they can’t rely on OS managed resources (ie OS File System file’s lock), but they are designed on the ActiveMQ 6’s LeaseDatabaseLocker idea that is as a couple of optimistic locks (live and backup) on the shared state table (i.e. `NODE_MANAGER_STORE`).


    Central to the correct behaviour of these locks is the database store configuration of 3 parameters:

    1. jdbc-lock-acquisition-timeout: The max allowed time in milliseconds while trying to acquire a JDBC lock. The default value is 60000 milliseconds (ie 60 seconds)
    2. jdbc-lock-renew-period: The period in milliseconds of the keep alive service of a JDBC lock. The default value is 2000 milliseconds (ie 2 seconds)
    3. jdbc-lock-expiration: The time in milliseconds a JDBC lock is considered valid without keeping it alive. The default value is 20000 milliseconds (ie 20 seconds)


    The first parameter is borrowed directly from the file based version, but exposed to the end user with a difference on the chosen default value: 60 seconds instead of been infinite (ie -1).


    The last 2 parameters are the ones that define the frequency of interactions with the database to allow a lock to be maintained as acquired: each party that acquire a lock will try to renew its owned lease every `jdbc-lock-renew-period`, each time extending its expiration period by `jdbc-lock-expiration`. The process of renewing the lease is supported by logs (warnings or errors) to alert if it won’t succeed to keep the pace (due to GC or DBMS slowness issues).

    From the reliability point of view instead, if just a single renew request would fail, the broker will invoke a shutdown due to IO error, in order to avoid any further operations on the shared store.


    The interested parties (live, backups) are not forced to have the same configured values for these parameters, because on the shared state table is recorded a DBMS Timestamp (HOLDER_EXPIRATION_TIME column) of the lock expiration time allowing anyone to query the state of the lock in isolation.


    Currently is used standard SQL syntax without any vendor specific customizations, hence it is supposed to work on any DBMS that support READ_COMMITTED and SERIALIZABLE isolation levels.


    Nice-to-Have Improvements


    The possible improvements on this feature are:

    • Write the user documentation to explain how it works/how to configure it
    • Write other unit tests on package private classes
    • Adapt the file based Shared Store tests to be used with the JDBC based one too
    • Hide the  jdbc-lock-acquisition-timeout configuration to the user and default it to infinite
    • Make the shared state table name customizable
    • Address clock time sync issues between DBMS and the brokers (it is already implemented, but need configuration/a better strategy to dealt with it)
    • Deal with DBMS fails of any kind (eg by providing a connection pool too)
    • Address the (un)reliable time window while renewing a lock: in the current form if a renew request is not triggered at all, the slowness will remain unnoticed