JdbcSemaphore implements AutoCloseable, Semaphore { @Override public void close() { synchronized (syncObj) { if (!isClosed) { releaseAll(); unregisterJmx(); this.heartBeat.removeLifecycleHook(failureHook); isClosed = true; } } } JdbcSemaphore(final DataSource dataSource, final String semaphoreName, final int nrPermits);  JdbcSemaphore(final DataSource dataSource, final String semaphoreName,
          final int nrPermits, final boolean strict);  JdbcSemaphore(final DataSource dataSource, final SemaphoreTablesDesc semTableDesc,
          final String semaphoreName, final int nrPermits, final int jdbcTimeoutSeconds,
          final boolean strictReservations); @SuppressFBWarnings({"CBX_CUSTOM_BUILT_XML", "STT_TOSTRING_STORED_IN_FIELD"}) // no sql builder (yet)  JdbcSemaphore(final DataSource dataSource, final SemaphoreTablesDesc semTableDesc,
          final String semaphoreName, final int nrPermits, final int jdbcTimeoutSeconds,
          final boolean strictReservations, final int acquirePollMillis); void registerJmx(); void unregisterJmx(); @SuppressFBWarnings("UW_UNCOND_WAIT") @CheckReturnValue @Override boolean tryAcquire(final int nrPermits, final long deadlineNanos); @Override @SuppressFBWarnings("EXS_EXCEPTION_SOFTENING_NO_CHECKED") void release(final int nrReservations); void releaseAll(); @JmxExport(description = "Get the available semaphore permits") int availablePermits(); @JmxExport(description = "get the number of permits owned by this process") int permitsOwned(); @JmxExport(description = "Get the total permits this semaphore can hand out") int totalPermits(); @JmxExport(description = "get a list of all dead owners which hold permits") @Nonnull List<OwnerPermits> getDeadOwnerPermits(final int wishPermits); @JmxExport(description = "release dead owner permits") @CheckReturnValue int releaseDeadOwnerPermits(@JmxExport(value = "wishPermits",
          description = "how many we whish to release") final int wishPermits); @JmxExport(description = "Change the total available permits to the provided number") void updatePermits(final int nrPermits); @JmxExport(description = "Reduce the total available permits by the provided number") void reducePermits(final int nrPermits); @JmxExport(description = "Increase the total available permits by the provided number") void increasePermits(final int nrPermits); int removeDeadHeartBeatAndNotOwnerRows(final long timeoutSeconds); @Override String toString(); @Override void close(); @JmxExport int getJdbcTimeoutSeconds(); @JmxExport boolean isIsHealthy();  }
@Test public void testSingleProcess() throws SQLException, IOException, InterruptedException, TimeoutException, ObjectCreationException, ObjectDisposeException { JdbcDataSource hds = new JdbcDataSource(); hds.setURL("jdbc:h2:mem:test"); hds.setUser("sa"); hds.setPassword("sa"); PooledDataSource ds = createPooledDS(hds); try (Connection conn = ds.getConnection()) { createSchemaObjects(ds); JdbcHeartBeat heartbeat = JdbcHeartBeat.getHeartBeatAndSubscribe(ds, HeartBeatTableDesc.DEFAULT, (JdbcHeartBeat.LifecycleHook) null); long lb = heartbeat.getLastRunDB(); LOG.debug("last TS = {}", Instant.ofEpochMilli(lb)); heartbeat.beat(); testReleaseAck(ds, "testSem", 2); testReleaseAck(ds, "testSem2", 2); heartbeat.close(); } ds.close(); }