Uploaded image for project: 'Aries'
  1. Aries
  2. ARIES-1920

Do not close the datasource if it wasn't created by JDBCConnectionProviderFactory

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 1.0
    • None
    • tx-control
    • None
    • Apache Karaf 4.2.6 + pax-jdbc + pax-jdbc-config + pax-jdbc-pool-dbcp2 + tx-control-service-xa + tx-control-provider-jdbc-xa

       

    Description

      Use case

      Shared datasource between bundles. Some of them are using plain javax.sql.DataSource (camel-jdbc), some are using TransactionControl.

      Steps to reproduce

      1. Register DataSource service using some pool (pax-jdbc-pool-dbcp2)
      2. Install bundle that
        1. Acquires Connection through JDBCConnectionProvider using previously registered datasource
        2. Uses the Connection through TransactionControl
      3. Restart the bundle

      Expected behaviour

      Possible to use connection

      Observed behaviour

      org.osgi.service.transaction.control.ScopedWorkException: The scoped work threw an exception
      ...
      Caused by: org.osgi.service.transaction.control.TransactionException: There was a problem getting hold of a database connection
      ...
      Caused by: java.lang.IllegalStateException: Pool not open
      

      Possible solution

      Do not close the underlying datasource if it wasn't created by JDBCConnectionProviderFactory

      Code sample

      @Reference
      TransactionControl transactionControl;
      
      @Reference
      JDBCConnectionProviderFactory jdbcConnectionProviderFactory;
      
      @Reference
      DataSource dataSource;
      
      private Connection connection;
      
      @Activate
      public void activate() throws Exception {
          Map<String, Object> props = new HashMap<>();
          props.put("osgi.connection.pooling.enabled", "false");
          props.put("osgi.xa.enabled", "false");
      
          JDBCConnectionProvider provider = jdbcConnectionProviderFactory.getProviderFor(dataSource, props);
      
          Connection = provider.getResource(transactionControl);
      
          transactionControl.notSupported(() -> {
              PreparedStatement stmt = connection.prepareStatement("SELECT 1 FROM dual");
              stmt.execute();
              return null;
          });
      }
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            kjchernov Konstantin J. Chernov
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: