So, who is osh?  Osh, what's the problem with invalid XA resource
state?

Aaron

On Wed, 18 Oct 2000, jBoss CVS Development wrote:
>   User: osh     
>   Date: 00/10/18 07:28:53
> 
>   Modified:    src/main/org/jboss/tm TxCapsule.java
>   Log:
>   Fix for possible race on instance reuse.
>   More trace information.
>   Still outstanding: A problem with invalid XA resource state during
>   XA resource calls.
>   
>   Revision  Changes    Path
>   1.15      +132 -36   jboss/src/main/org/jboss/tm/TxCapsule.java
>   
>   Index: TxCapsule.java
>   ===================================================================
>   RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/tm/TxCapsule.java,v
>   retrieving revision 1.14
>   retrieving revision 1.15
>   diff -u -r1.14 -r1.15
>   --- TxCapsule.java  2000/10/15 19:05:07     1.14
>   +++ TxCapsule.java  2000/10/18 14:28:53     1.15
>   @@ -43,7 +43,7 @@
>     *  @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
>     *  @author <a href="mailto:[EMAIL PROTECTED]">Ole Husgaard</a>
>     *
>   - *  @version $Revision: 1.14 $
>   + *  @version $Revision: 1.15 $
>     */
>    class TxCapsule implements TimeoutTarget
>    {
>   @@ -87,6 +87,9 @@
>       {
>          xid = new XidImpl();
>          this.tm = tm;
>   +
>   +      if (trace)
>   +         Logger.debug("TxCapsule: Created new instance for tx=" + toString());
>       }
>    
>       /**
>   @@ -118,6 +121,9 @@
>    
>          start = System.currentTimeMillis();
>          this.timeout = TimeoutFactory.createTimeout(start+timeout, this);
>   +
>   +      if (trace)
>   +         Logger.debug("TxCapsule: Reused instance for tx=" + toString());
>       }
>    
>       // Public --------------------------------------------------------
>   @@ -130,7 +136,8 @@
>          try {
>             lock();
>    
>   -         Logger.warning("Transaction " + toString() + " timed out.");
>   +         Logger.warning("Transaction " + toString() + " timed out." +
>   +                        " status=" + getStringStatus(status));
>    
>             if (this.timeout == null)
>                return; // Don't race with timeout cancellation.
>   @@ -167,6 +174,7 @@
>                rollbackResources();
>                doAfterCompletion();
>                gotHeuristic(null, XAException.XA_HEURRB);
>   +            instanceDone();
>                return;
>    
>             case Status.STATUS_PREPARING:
>   @@ -174,7 +182,8 @@
>                return; // commit will fail
>    
>             default:
>   -            Logger.warning("TxCapsule: Unknown status at timeout.");
>   +            Logger.warning("TxCapsule: Unknown status at timeout, tx=" +
>   +                           toString());
>                return;
>             }
>          } finally {
>   @@ -225,8 +234,8 @@
>             lock();
>    
>             if (trace)
>   -            Logger.debug("TxCapsule.commit(): Entered, status=" +
>   -                         getStringStatus(status));
>   +            Logger.debug("TxCapsule.commit(): Entered, tx=" + toString() +
>   +                         " status=" + getStringStatus(status));
>    
>             switch (status) {
>             case Status.STATUS_PREPARING:
>   @@ -268,7 +277,8 @@
>    
>             if (trace)
>                Logger.debug("TxCapsule.commit(): Before completion done, " +
>   -                         "status=" + getStringStatus(status));
>   +                         "tx=" + toString() +
>   +                         " status=" + getStringStatus(status));
>    
>             endResources();
>    
>   @@ -309,8 +319,8 @@
>                doAfterCompletion();
>                cancelTimeout();
>                instanceDone();
>   -            throw new RollbackException("Unable to commit, status=" +
>   -                                        getStringStatus(status));
>   +            throw new RollbackException("Unable to commit, tx=" + toString() +
>   +                                        " status=" + getStringStatus(status));
>             }
>    
>             cancelTimeout();
>   @@ -319,7 +329,8 @@
>             checkHeuristics();
>    
>             if (trace)
>   -            Logger.debug("TxCapsule.commit(): Committed OK.");
>   +            Logger.debug("TxCapsule.commit(): Transaction " + toString() +
>   +                         " committed OK.");
>    
>          } finally {
>            unlock();
>   @@ -340,8 +351,8 @@
>             lock();
>    
>             if (trace)
>   -            Logger.debug("TxCapsule.rollback(): Entered, status=" +
>   -                         getStringStatus(status));
>   +            Logger.debug("TxCapsule.rollback(): Entered, tx=" + toString() +
>   +                         " status=" + getStringStatus(status));
>    
>             switch (status) {
>             case Status.STATUS_ACTIVE:
>   @@ -361,7 +372,9 @@
>                status = Status.STATUS_MARKED_ROLLBACK;
>                return; // commit() will do rollback.
>             default:
>   -            throw new IllegalStateException("Cannot rollback(), status=" +
>   +            throw new IllegalStateException("Cannot rollback(), " +
>   +                                            "tx=" + toString() +
>   +                                            " status=" +
>                                                getStringStatus(status));
>             }
>          } finally {
>   @@ -383,8 +396,8 @@
>             lock();
>    
>             if (trace)
>   -            Logger.debug("TxCapsule.setRollbackOnly(): Entered, status=" +
>   -                         getStringStatus(status));
>   +            Logger.debug("TxCapsule.setRollbackOnly(): Entered, tx=" +
>   +                         toString() + " status=" + getStringStatus(status));
>    
>             switch (status) {
>             case Status.STATUS_ACTIVE:
>   @@ -438,8 +451,8 @@
>             lock();
>    
>             if (trace)
>   -            Logger.debug("TxCapsule.delistResource(): Entered, status=" +
>   -                         getStringStatus(status));
>   +            Logger.debug("TxCapsule.delistResource(): Entered, tx=" +
>   +                         toString() + " status=" + getStringStatus(status));
>    
>             int idx = findResource(xaRes);
>    
>   @@ -481,6 +494,8 @@
>                }
>                return true;
>             } catch(XAException e) {
>   +            Logger.warning("XAException: tx=" + toString() + " errorCode=" +
>   +                           getStringXAErrorCode(e.errorCode));
>                Logger.exception(e);
>                status = Status.STATUS_MARKED_ROLLBACK;
>                return false;
>   @@ -509,8 +524,8 @@
>             lock();
>    
>             if (trace)
>   -            Logger.debug("TxCapsule.enlistResource(): Entered, status=" +
>   -                         getStringStatus(status));
>   +            Logger.debug("TxCapsule.enlistResource(): Entered, tx=" +
>   +                         toString() + " status=" + getStringStatus(status));
>    
>             switch (status) {
>             case Status.STATUS_ACTIVE:
>   @@ -569,6 +584,8 @@
>                addResource(xaRes);
>                return true;
>             } catch(XAException e) {
>   +            Logger.warning("XAException: tx=" + toString() + " errorCode=" +
>   +                           getStringXAErrorCode(e.errorCode));
>                Logger.exception(e);
>                return false;
>             }
>   @@ -603,7 +620,8 @@
>    
>             if (trace)
>                Logger.debug("TxCapsule.registerSynchronization(): Entered, " +
>   -                         "status=" + getStringStatus(status));
>   +                         "tx=" + toString() +
>   +                         " status=" + getStringStatus(status));
>    
>             switch (status) {
>             case Status.STATUS_ACTIVE:
>   @@ -796,15 +814,76 @@
>       }
>    
>       /**
>   +    *  Return a string representation of the given XA error code.
>   +    */
>   +   private String getStringXAErrorCode(int errorCode) {
>   +      switch (errorCode) {
>   +         case XAException.XA_HEURCOM:
>   +            return "XA_HEURCOM";
>   +         case XAException.XA_HEURHAZ:
>   +            return "XA_HEURHAZ";
>   +         case XAException.XA_HEURMIX:
>   +            return "XA_HEURMIX";
>   +         case XAException.XA_HEURRB:
>   +            return "XA_HEURRB";
>   +
>   +         case XAException.XA_NOMIGRATE:
>   +            return "XA_NOMIGRATE";
>   +
>   +         case XAException.XA_RBCOMMFAIL:
>   +            return "XA_RBCOMMFAIL";
>   +         case XAException.XA_RBDEADLOCK:
>   +            return "XA_RBDEADLOCK";
>   +         case XAException.XA_RBINTEGRITY:
>   +            return "XA_RBINTEGRITY";
>   +         case XAException.XA_RBOTHER:
>   +            return "XA_RBOTHER";
>   +         case XAException.XA_RBPROTO:
>   +            return "XA_RBPROTO";
>   +         case XAException.XA_RBROLLBACK:
>   +            return "XA_RBROLLBACK";
>   +         case XAException.XA_RBTIMEOUT:
>   +            return "XA_RBTIMEOUT";
>   +         case XAException.XA_RBTRANSIENT:
>   +            return "XA_RBTRANSIENT";
>   +
>   +         case XAException.XA_RDONLY:
>   +            return "XA_RDONLY";
>   +         case XAException.XA_RETRY:
>   +            return "XA_RETRY";
>   +
>   +         case XAException.XAER_ASYNC:
>   +            return "XAER_ASYNC";
>   +         case XAException.XAER_DUPID:
>   +            return "XAER_DUPID";
>   +         case XAException.XAER_INVAL:
>   +            return "XAER_INVAL";
>   +         case XAException.XAER_NOTA:
>   +            return "XAER_NOTA";
>   +         case XAException.XAER_OUTSIDE:
>   +            return "XAER_OUTSIDE";
>   +         case XAException.XAER_PROTO:
>   +            return "XAER_PROTO";
>   +         case XAException.XAER_RMERR:
>   +            return "XAER_RMERR";
>   +         case XAException.XAER_RMFAIL:
>   +            return "XAER_RMFAIL";
>   + 
>   +         default:
>   +            return "XA_UNKNOWN(" + errorCode + ")";
>   +      }
>   +   }
>   +
>   +   /**
>        *  Lock this instance.
>        */
>       private synchronized void lock()
>       {
>          if (done)
>   -         throw new IllegalStateException("No transaction");
>   +         throw new IllegalStateException("Transaction has terminated");
>    
>          if (locked) {
>   -         Logger.warning("TxCapsule: Lock contention."); // Good for debugging.
>   +         Logger.warning("TxCapsule: Lock contention, tx=" + toString());
>             Thread.currentThread().dumpStack();
>    
>             long myIncarnation = incarnationCount;
>   @@ -813,11 +892,15 @@
>                try {
>                   wait();
>                } catch (InterruptedException ex) {}
>   +
>   +            // MF FIXME: don't we need a notify() in this case?
>   +            // we need to release all the thread waiting on this lock 
>    
>   -                   // MF FIXME: don't we need a notify() in this case?
>   -                   // we need to release all the thread waiting on this lock 
>   +            // OSH: notifyAll() is done in instanceDone()
>   +            // and notify() is done in unlock().
>   +
>                if (done || myIncarnation != incarnationCount)
>   -              throw new IllegalStateException("No transaction");
>   +              throw new IllegalStateException("Transaction has now terminated");
>             }
>          }
>    
>   @@ -829,8 +912,11 @@
>        */
>       private synchronized void unlock()
>       {
>   -      if (!locked)
>   -         Logger.warning("TxCapsule: Unlocking, but not locked.");
>   +      if (!locked) {
>   +         Logger.warning("TxCapsule: Unlocking, but not locked, tx=" +
>   +                        toString());
>   +         Logger.exception(new Exception("[Stack trace]"));
>   +      }
>    
>          locked = false;
>    
>   @@ -918,6 +1004,7 @@
>                       ") entered: " + xaRes.toString() +
>                       " flags=" + flags);
>          unlock();
>   +      // OSH FIXME: resourceState could be incorrect during this callout.
>          try {
>             xaRes.start(xid, flags);
>          } finally {
>   @@ -935,17 +1022,18 @@
>       private void endResource(XAResource xaRes, int flag)
>          throws XAException
>       {
>   -        Logger.debug("TxCapsule.endResource(" + xid.toString() +
>   +      Logger.debug("TxCapsule.endResource(" + xid.toString() +
>                       ") entered: " + xaRes.toString() +
>                       " flag=" + flag);
>          unlock();
>   +      // OSH FIXME: resourceState could be incorrect during this callout.
>          try {
>             xaRes.end(xid, flag);
>          } finally {
>             lock();
>   -        Logger.debug("TxCapsule.endResource(" + xid.toString() +
>   -                   ") leaving: " + xaRes.toString() +
>   -                   " flag=" + flag);
>   +         Logger.debug("TxCapsule.endResource(" + xid.toString() +
>   +                      ") leaving: " + xaRes.toString() +
>   +                      " flag=" + flag);
>          }
>       }
>    
>   @@ -978,8 +1066,8 @@
>                  resourceState[i] = RS_ENDED;
>                }
>             } catch(XAException e) {
>   -            Logger.debug("endresources: XAException: " + e);
>   -            Logger.debug("endresources: XAException: errorCode=" + e.errorCode);
>   +            Logger.warning("XAException: tx=" + toString() + " errorCode=" +
>   +                           getStringXAErrorCode(e.errorCode));
>                Logger.exception(e);
>                status = Status.STATUS_MARKED_ROLLBACK;
>             }
>   @@ -1061,6 +1149,8 @@
>                unlock();
>                resource.forget(xid);
>             } catch (XAException e) {
>   +            Logger.warning("XAException at forget(): errorCode=" +
>   +                           getStringXAErrorCode(e.errorCode));
>                Logger.exception(e);
>             } finally {
>                lock();
>   @@ -1107,6 +1197,10 @@
>        */
>       private void instanceDone()
>       {
>   +      // Notify transaction fronts that we are done.
>   +      for (int i = 0; i < transactionCount; ++i)
>   +        transactions[i].setDone();
>   +
>          synchronized (this) {
>             // Done with this incarnation.
>             ++incarnationCount;
>   @@ -1119,10 +1213,6 @@
>             notifyAll();
>          }
>    
>   -      // Notify transaction fronts that we are done.
>   -      for (int i = 0; i < transactionCount; ++i)
>   -        transactions[i].setDone();
>   -
>          // Clear content of collections.
>          syncCount = 0;
>          transactionCount = 0;
>   @@ -1193,6 +1283,8 @@
>                      status = Status.STATUS_MARKED_ROLLBACK;
>                   break;
>                default:
>   +               Logger.warning("XAException: tx=" + toString() + " errorCode=" +
>   +                              getStringXAErrorCode(e.errorCode));
>                   Logger.exception(e);
>                   if (status == Status.STATUS_PREPARING)
>                      status = Status.STATUS_MARKED_ROLLBACK;
>   @@ -1240,6 +1332,8 @@
>                   gotHeuristic(resources[i], e.errorCode);
>                   break;
>                default:
>   +               Logger.warning("XAException: tx=" + toString() + " errorCode=" +
>   +                              getStringXAErrorCode(e.errorCode));
>                   Logger.exception(e);
>                   break;
>                }
>   @@ -1281,6 +1375,8 @@
>                   gotHeuristic(resources[i], e.errorCode);
>                   break;
>                default:
>   +               Logger.warning("XAException: tx=" + toString() + " errorCode=" +
>   +                              getStringXAErrorCode(e.errorCode));
>                   Logger.exception(e);
>                   break;
>                }
>   
>   
>   
> 


Reply via email to