Uploaded image for project: 'Application Server 3  4  5 and 6'
  1. Application Server 3 4 5 and 6
  2. JBAS-8626

QueuedPessimisticEJBLock is released too early

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • No Release
    • JBossAS-3.2.7 Final, JBossAS-5.1.0.GA
    • None
    • None

      Usecase:
      All xx, xy, yy and xz are representing readonly entitybean-methods and are called on one EntityBean. CMT required and reentrant true.
      The following methods are executed on the server in this order:

      Thread1: calls entitybean.xx
      Thread1: calls entitybean.xy
      Thread2: calls entitybean.yy -> has to wait for the QueuedPessimisticEJBLock
      Thread1: returns from entitybean.xy and frees the QueuedPessimisticEJBLock <--- BUG
      Thread2: gets the QueuedPessimisticEJBLock but doesn't get the NonReentrantLock
      Thread1: calls entitybean.xz -> has to wait for the QueuedPessimisticEJBLock and still holds the NonReentrantLock
      Result: Undetected deadlock between QueuedPessimisticEJBLock and NonReentrantLock.

      Please use the attached bug-0.1-SNAPSHOT.jar for verification. Main class for the test is locking.bug.DeadlockTest.

      Our current workaround:
      Created a subclass of QueuedPessimisticEJBLock and override problematic method "endInvocation":

      public void endInvocation(Invocation P_mi)
      {
      Transaction F_tx = P_mi.getTransaction();
      if (F_tx != null && F_tx.equals(getTransaction()))
      {
      EntityEnterpriseContext F_ctx = (EntityEnterpriseContext)P_mi.getEnterpriseContext();

      if(F_ctx == null)

      { endTransaction(F_tx); }

      else if(F_ctx.hasTxSynchronization() == false)
      {
      NonReentrantLock F_mLock = F_ctx.getMethodLock();

      if (F_mLock == null)

      { endTransaction(F_tx); }

      else
      {
      Object F_resourceHolder = F_mLock.getResourceHolder();
      if (F_resourceHolder instanceof Thread
      && Thread.currentThread().equals(F_resourceHolder))

      { // don't end the transaction, because we still own the // lock! }
      else if (F_resourceHolder instanceof Transaction
      && F_tx.equals(F_resourceHolder))
      { // don't end the transaction, because we still own the // lock! }

      else

      { endTransaction(F_tx); }

      }
      }
      else

      { //hasTxSynchronization is true -> don't end the transaction }

      }
      }

        1. jboss_logfile.log
          71 kB
          Judith Bürgstein

              Unassigned Unassigned
              buej_jira Judith Bürgstein (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated: