docs: @Override
      public void cancel() throws IllegalStateException, NoSuchObjectLocalException, EJBException
      {
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
          if (isTraceOn && tc.isEntryEnabled())
              Tr.entry(tc, "cancel: " + this);
  
          // Determine if the calling bean is in a state that allows timer service
          // method access - throws IllegalStateException if not allowed.
          checkTimerAccess();
  
          // Determine if this timer is considered cancelled for the current
          // thread/transaction - throws NoSuchObjectLocalException if cancelled.
          checkIfCancelled();
  
          // -----------------------------------------------------------------------
          // Concurrency behavior for Non-persistent timer cancel:         RTC107334
          //
          // Concurrent Cancel and getTimers() / Expiration
          // - Once cancel has called (but before the transaction commits), timer
          //   expiration will not occur and getTimers() will not return the
          //   cancelled timer. If rollback occurs, the timer will be re-scheduled
          //   and once again be returned by getTimers().
          // > Differs from persistent timers; persistent timers may or may not
          //   block expiration (depending on database); but getTimers() would
          //   return the timer until the cancel commits. Difference in getTimers()
          //   behavior maintained since it was originally implemented that way
          //   and would cause no significant problem for applications.
          //
          // Concurrent Cancel and Expiration:
          // - If cancel occurs just before the timeout begins running, then the
          //   timer will not run; unless rollback occurs, then it will be
          //   re-scheduled and run immediately.
          // - If the timeout method has started running, the cancel will not be
          //   blocked; however the timer will not re-schedule if it fails. The
          //   cancel transaction will be able to complete even if the timer
          //   is still running; but all other attempts to access it will
          //   report it does not exist.
          // - If the cancel rolls back while the timer is running, the code will
          //   insure it is only re-scheduled one time.
          // > Differs from persistent timers largely depending on database;
          //   closer to the behavior of using optimistic locking (Oracle).
          //
          // Concurrent Cancels
          // - Neither cancel will be blocked; the timer will not run if
          //   expiration occurs after either cancel is called.
          // - Both transactions will be allowed to commit; the timer will be
          //   permanently destroyed after the first commit.
          // - If one commits, then the other rolls back, the rollback will have
          //   no effect on the timer; it has been permanently removed.
          // - If one rolls back, then the other one commits; the roll back will
          //   re-schedule the timer, then the commit will remove it again and
          //   permanently delete it.
          // - There is a possibility the timer may run after the first one rolls
          //   back and the second one commits.
          // > Differs from persistent timers largely depending on database;
          //   closer to the behavior of using optimistic locking (Oracle), where
          //   both commits are allowed to proceed.
          // -----------------------------------------------------------------------
  
          ContainerTx tx = ivContainer.getCurrentContainerTx();
  
          if (tx != null)
          {
              boolean queuedToStart = (tx.timersQueuedToStart != null) ? tx.timersQueuedToStart.remove(ivTaskId) != null : false;
              if (queuedToStart) {
                  // If this timer was also created in the same transaction, then it
                  // just needs to be removed from the queue of timers to start, and
                  // remove called with destroy=true to update state; the cancel
                  // cannot ever be rolled back.
                  remove(true);
              } else {
                  // Remove from the active timers map and cancel, but do not permanently
                  // remove to permit restore on rollback.
                  remove(false);
  
                  if (tx.timersCanceled == null) {
                      tx.timersCanceled = new LinkedHashMap<String, TimerNpImpl>();
                  }
                  tx.timersCanceled.put(ivTaskId, this);
              }
          }
          else
          {
              // Here for backward compatibility. Could only occur for EJB 1.1
              // module with BMT bean, which the customer has re-coded to
              // implement TimedObject.
  
              // Remove from the active timers map and cancel permanently (destroy)
              remove(true);
          }
  
          if (ivTimeoutThread == Thread.currentThread()) {
              // clear the firing thread; subsequent attempts to access this timer
              // will result in NoSuchObjectLocalException.                 RTC127173
              ivTimeoutThread = null;
          }
  
          if (isTraceOn && tc.isEntryEnabled())
              Tr.exit(tc, "cancel: successful");
      }