docs: protected void performInvalidation() {
          if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
              LoggingUtil.SESSION_LOGGER_WAS.entering(methodClassName, methodNames[PERFORM_INVALIDATION]);
          }
  
          long now = System.currentTimeMillis();
          PreparedStatement ps1 = null;
          ResultSet rs1 = null;
          PreparedStatement ps2 = null;
  
          boolean ps1Closed = false;
          boolean ps2Closed = false;
  
          Connection nukerCon = null;
  
          // do some initializations
          String appName = getIStore().getId(); //bhSessionContext.getAppName();
  
          boolean doInvals = false;
          boolean doDatabaseInval = doScheduledInvalidation();
          nukerCon = getConnection(false);
  
          if (nukerCon == null) {
              if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINER)) {
                  LoggingUtil.SESSION_LOGGER_WAS.exiting(methodClassName, methodNames[PERFORM_INVALIDATION], "Connection is null");
              }
              return;
          }
  
          try {
  
              // handle last acc times for manual update irregardless
              // of whether this thread will scan for time outs
              if (!_smc.getEnableEOSWrite()) {
                  writeCachedLastAccessedTimes(nukerCon);
              }
  
              //check the value of doDatabaseInval
              if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                  LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE,methodClassName, methodNames[PERFORM_INVALIDATION], "doDatabaseInval="+doDatabaseInval);
              }
  
              if (doDatabaseInval) {
                  ps1 = nukerCon.prepareStatement(readLastAccess);
                  ps1.setString(1, appName);
                  ps1.setString(2, appName);
                  ps1.setString(3, appName);
                  rs1 = ps1.executeQuery();
  
                  boolean rowExists = false;
                  long lastTime = 0L;
                  if (rs1.next()) {
                      rowExists = true;
                      lastTime = rs1.getLong(1);
                  }
                  rs1.close();
                  ps1.close();
                  ps1Closed = true;
  
                  //check the value of rowExists
                  if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                      LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE,methodClassName, methodNames[PERFORM_INVALIDATION], "rowExists="+rowExists);
                  }
  
                  if (rowExists) {
                      long lastCheck = now - _smc.getInvalidationCheckInterval() * 1000;
  
                      //check the value of lastCheck,lastTime,now
                      if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                          LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE,methodClassName, methodNames[PERFORM_INVALIDATION], "lastCheck="+lastCheck+",lastTime="+lastTime+",now="+now);
                      }
  
                      //if no other server tried to process invalidation within the interval, this will be true
                      //similar to updateNukerTimeStamp, but we have an extra check here to test the last access time hasn't changed
                      //PK30585 - added future time check
                      if ((lastCheck >= lastTime) || (lastTime > now)) {
                          ps2 = nukerCon.prepareStatement(optUpdate);
                          setPSLong(ps2, 1, now);
                          ps2.setString(2, appName);
                          ps2.setString(3, appName);
                          ps2.setString(4, appName);
                          setPSLong(ps2, 5, lastTime);
                          int res = ps2.executeUpdate();
                          if (res > 0)
                              doInvals = true;
                      }
                  } else {
                      //If we are here means, this is the first time this web module is
                      //trying to invalidation of sessions
                      ps2 = nukerCon.prepareStatement(insForInval);
                      ps2.setString(1, appName);
                      ps2.setString(2, appName);
                      ps2.setString(3, appName);
                      setPSLong(ps2, 4, now);
                      ps2.setInt(5, -1);
                      try {
                          ps2.executeUpdate();
                          doInvals = true;
                      } catch (SQLException sqle) {
                          //                        if (isDuplicateKeyException(sqle)) {
                          //                            // ignore duplicate key errror here - can only happen in very small timing window but causes no harm
                          //                            if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled()&&LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                          //                                LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE, methodClassName, methodNames[PERFORM_INVALIDATION], "Duplicate key inserted");
                          //                            }
                          //                        } else {
                          throw sqle; // to be re-caught and logged below
                          //                        }
                      }
                  }
  
                  if (ps2 != null)
                      ps2.close();
                  ps2Closed = true;
  
                  //check the value of doInvals
                  if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINE)) {
                      LoggingUtil.SESSION_LOGGER_WAS.logp(Level.FINE,methodClassName, methodNames[PERFORM_INVALIDATION], "doInvals="+doInvals);
                  }
  
                  if (doInvals) {
  
                      //Process the non-listener sessions first
                      doInvalidations(nukerCon);
  
                      //Read in all the sessions with listeners that need to be invalidated
                      Enumeration e = pollForInvalidSessionsWithListeners(nukerCon);
                      processInvalidListeners(e, nukerCon);
  
                  }
  
              }
  
          } catch (Throwable t) {
              com.ibm.ws.ffdc.FFDCFilter.processException(t, "com.ibm.ws.session.store.db.DatabaseHashMap.performInvalidation", "2537", this);
              LoggingUtil.SESSION_LOGGER_WAS.logp(Level.SEVERE, methodClassName, methodNames[PERFORM_INVALIDATION], "DatabaseHashMap.performInvalidationError");
              LoggingUtil.SESSION_LOGGER_WAS.logp(Level.SEVERE, methodClassName, methodNames[PERFORM_INVALIDATION], "CommonMessage.exception", t);
          } finally {
              if (!ps1Closed && rs1 != null)
                  closeResultSet(rs1);
              if (!ps1Closed && ps1 != null)
                  closeStatement(ps1);
              if (!ps2Closed && ps2 != null)
                  closeStatement(ps2);
              closeConnection(nukerCon);
          }
          if (com.ibm.websphere.ras.TraceComponent.isAnyTracingEnabled() && LoggingUtil.SESSION_LOGGER_WAS.isLoggable(Level.FINER)) {
              LoggingUtil.SESSION_LOGGER_WAS.exiting(methodClassName, methodNames[PERFORM_INVALIDATION]);
          }
      }