Skip to content
This repository has been archived by the owner on Nov 16, 2021. It is now read-only.

RFC-221 Transaction control: Release resources managed by JDBCConnectionProvider #32

Open
bjhargrave opened this issue Dec 7, 2016 · 4 comments
Assignees
Labels
publiccomment Public comment

Comments

@bjhargrave
Copy link
Member

Original bug ID: BZ#203
From: Karel Haeck <karel.haeck@telenet.be>
Reported version: unspecified

@bjhargrave
Copy link
Member Author

Comment author: Karel Haeck <karel.haeck@telenet.be>

If one obtains a JDBCConnectionProvider by using one of the getProviderFor methods on JDBCConnectionProviderFactory, the returned JDBCConnectionProvider basically encapsulates an JDBC database connection pool. Currently there is no portable way to shutdown the underlying pool managed by the returned JDBCConnectionProvider instance.
Given the dynamic nature of OSGi components, this may result in a large number of open, unused database connections.
Suggestion: Have JDBCConnectionProvider or its parent interface ResourceProvider extend AutoCloseable

@bjhargrave
Copy link
Member Author

Comment author: @timothyjward

(In reply to Karel Haeck from comment BZ#0)

If one obtains a JDBCConnectionProvider by using one of the getProviderFor
methods on JDBCConnectionProviderFactory, the returned
JDBCConnectionProvider basically encapsulates an JDBC database connection
pool. Currently there is no portable way to shutdown the underlying pool
managed by the returned JDBCConnectionProvider instance.
Given the dynamic nature of OSGi components, this may result in a large
number of open, unused database connections.
Suggestion: Have JDBCConnectionProvider or its parent interface
ResourceProvider extend AutoCloseable

There are two ways to obtain a ResourceProvider:

  1. By using a factory service, such as a JDBCConnectionProviderFactory
  2. By looking up the ResourceProvider in the service registry

Having the ResourceProvider be AutoCloseable causes very significant problems with the second mode of operation. If any bundle can close the ResourceProvider then they are at risk of breaking the Resources being used elsewhere in the system.

The way that the RI handles cleanup is portable, and works as follows:

  1. For resources created by factory services, the resources are closed when either
    a) The creating factory service is released (i.e. the factory is provided using a ServiceFactory and shuts down its created resources when it is no longer in used)
    b) The resource factory bundle is stopped.

  2. Resources registered directly in the service registry can:

    a) Use a ServiceFactory and shut down when not used
    b) Shut down when they get unregistered (e.g. their configuration is deleted or the bundle is stopped

This mechanism has been shown to work for JPA and JDBC (see https://github.com/apache/aries/tree/trunk/tx-control). There is even a common provider which supports lifecycle aware, configuration managed resources of arbitrary types.

I would be happy to clarify in the specification chapter that the ResourceProvider should be invalidated when the factory is released (although this is implicit from the core specification).

@bjhargrave
Copy link
Member Author

Comment author: Karel Haeck <karel.haeck@telenet.be>

While the proposed logic may prevent resource leakage in the majority of use cases, there still is a potential resource leakage when one bundle creates multiple JDBCConnectionProviders.

A typical example would be a bundle that provides Configuration Admin support to configure multiple instances of JDBCConnectionProviders connected to different databases (or to the same database using different database credentials). Actually this is a bundle that uses 1. to implement 2. By default a bundle only has a single instance of the JDBCConnectionProviderFactory service, so when a configuration is deleted or changed, the corresponding connection pool will not be shutdown, and the shutdown has to be done in implementation specific way.

One could mandate that the JDCConnectionProviderFactory service is registered as a PrototypeServiceFactory, but this would still require collaboration from the using bundle to use the prototype api and only create one JDBCConnectionProvider instance per factory instance.

I agree that extending AutoCloseable is not desirable for operation mode 2. .
A better idea may be to have a release(JDBConnectionProvider) method on JDCBConnectionProviderFactory, so that anyone who obtains a ConnectionProvider can properly close it, and use the cleanup based on the JDBCConnectionProviderFactory instance life cycle as backup.

@bjhargrave
Copy link
Member Author

Comment author: @timothyjward

(In reply to Karel Haeck from comment BZ#2)

While the proposed logic may prevent resource leakage in the majority of use
cases, there still is a potential resource leakage when one bundle creates
multiple JDBCConnectionProviders.

A typical example would be a bundle that provides Configuration Admin
support to configure multiple instances of JDBCConnectionProviders connected
to different databases (or to the same database using different database
credentials). Actually this is a bundle that uses 1. to implement 2. By
default a bundle only has a single instance of the
JDBCConnectionProviderFactory service, so when a configuration is deleted or
changed, the corresponding connection pool will not be shutdown, and the
shutdown has to be done in implementation specific way.

I don't agree with this particular use case, as the ManagedServiceFactory described should really be integrated with the JDBC Resource provider implementation. Effectively the described bundle is a piece of middleware for providing a Configuration Defined Resource, and by integrating this with a particular provider it be able to advertise a full metatype, including any implementation specific configuration properties. Note that this is exactly what the proposed reference implementation provides.

That said, the overall scenario does bear some consideration. There is potentially an issue with lifecycle where a component uses the factory and wishes to provide dynamic reconfiguration (perhaps just changing some pooling properties, but potentially changing connection details). Currently there is no way to configure a new Resource Provider and release the existing one without a gap in availability. We can discuss this within the EEG.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
publiccomment Public comment
Projects
None yet
Development

No branches or pull requests

2 participants