User: patriot1burke
Date: 02/01/12 12:21:07
Modified: src/main/org/jboss/ejb/plugins/lock
QueuedPessimisticEJBLock.java BeanLockSupport.java
Log:
Added deadlock detection. If application deadlock is detected and RuntimeException
is thrown so
that the thread does not hang until TX timeout. It will be extremely helpful in
debugging.
Revision Changes Path
1.8 +81 -54
jboss/src/main/org/jboss/ejb/plugins/lock/QueuedPessimisticEJBLock.java
Index: QueuedPessimisticEJBLock.java
===================================================================
RCS file:
/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/lock/QueuedPessimisticEJBLock.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- QueuedPessimisticEJBLock.java 2001/12/19 06:04:48 1.7
+++ QueuedPessimisticEJBLock.java 2002/01/12 20:21:07 1.8
@@ -36,7 +36,7 @@
* @author <a href="[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="[EMAIL PROTECTED]">Bill Burke</a>
*
- * @version $Revision: 1.7 $
+ * @version $Revision: 1.8 $
*
* <p><b>Revisions:</b><br>
* <p><b>2001/08/03: billb</b>
@@ -238,59 +238,85 @@
protected boolean waitForTx(Transaction miTx, boolean trace) throws Exception
{
boolean wasScheduled = false;
-
- // Do we have a running transaction with the context?
- // We loop here until either until success or until transaction timeout
- // If we get out of the loop successfully, we can successfully
- // set the transaction on this puppy.
- while (this.tx != null &&
- // And are we trying to enter with another transaction?
- !this.tx.equals(miTx))
- {
- wasScheduled = true;
- // That's no good, only one transaction per context
- // Let's put the thread to sleep the transaction demarcation will wake
them up
- if( trace ) log.trace("Transactional contention on context"+id);
-
- TxLock txLock = getTxLock(miTx);
-
- if( trace ) log.trace("Begin wait on Tx="+this.tx);
-
- // And lock the threads on the lock corresponding to the Tx in MI
- synchronized(txLock)
- {
- releaseSync();
- try
- {
- txLock.wait(txTimeout);
- } catch (InterruptedException ignored) {}
- } // end synchronized(txLock)
-
- this.sync();
-
- if( trace ) log.trace("End wait on TxLock="+this.tx);
- if (isTxExpired(miTx))
- {
- log.error(Thread.currentThread() + "Saw rolled back tx="+miTx+" waiting
for txLock"
- // +" On method: " + mi.getMethod().getName()
- // +" txWaitQueue size: " + txWaitQueue.size()
- );
- if (txLock.isQueued)
- {
- // Remove the TxLock from the queue because this thread is exiting.
- // Don't worry about notifying other threads that share the same
transaction.
- // They will timeout and throw the below RuntimeException
- txLocks.remove(txLock);
- txWaitQueue.remove(txLock);
- }
- else if (this.tx != null && tx.equals(miTx))
- {
- // We're not qu
- nextTransaction();
- }
- throw new RuntimeException("Transaction marked for rollback, possibly a
timeout");
- }
- } // end while(tx!=miTx)
+ boolean addedWaiting = false;
+ try
+ {
+ // Do we have a running transaction with the context?
+ // We loop here until either until success or until transaction timeout
+ // If we get out of the loop successfully, we can successfully
+ // set the transaction on this puppy.
+ while (this.tx != null &&
+ // And are we trying to enter with another transaction?
+ !this.tx.equals(miTx))
+ {
+ // For deadlock detection.
+ // miTx is waiting for this.tx to finish so put it
+ // in the waiting table and do deadlock detection.
+ if (miTx != null && !addedWaiting)
+ {
+ synchronized (waiting)
+ {
+ waiting.put(miTx, this.tx);
+ addedWaiting = true;
+ }
+ deadlockDetection(miTx);
+ }
+ wasScheduled = true;
+ // That's no good, only one transaction per context
+ // Let's put the thread to sleep the transaction demarcation will wake
them up
+ if( trace ) log.trace("Transactional contention on context"+id);
+
+ TxLock txLock = getTxLock(miTx);
+
+ if( trace ) log.trace("Begin wait on Tx="+this.tx);
+
+ // And lock the threads on the lock corresponding to the Tx in MI
+ synchronized(txLock)
+ {
+ releaseSync();
+ try
+ {
+ txLock.wait(txTimeout);
+ } catch (InterruptedException ignored) {}
+ } // end synchronized(txLock)
+
+ this.sync();
+
+ if( trace ) log.trace("End wait on TxLock="+this.tx);
+ if (isTxExpired(miTx))
+ {
+ log.error(Thread.currentThread() + "Saw rolled back tx="+miTx+" waiting
for txLock"
+ // +" On method: " + mi.getMethod().getName()
+ // +" txWaitQueue size: " + txWaitQueue.size()
+ );
+ if (txLock.isQueued)
+ {
+ // Remove the TxLock from the queue because this thread is exiting.
+ // Don't worry about notifying other threads that share the same
transaction.
+ // They will timeout and throw the below RuntimeException
+ txLocks.remove(txLock);
+ txWaitQueue.remove(txLock);
+ }
+ else if (this.tx != null && tx.equals(miTx))
+ {
+ // We're not qu
+ nextTransaction();
+ }
+ throw new RuntimeException("Transaction marked for rollback, possibly a
timeout");
+ }
+ } // end while(tx!=miTx)
+ }
+ finally
+ {
+ // miTx is now long waiting for a tx to finish so remove it from the waiting
table.
+ if (miTx != null && addedWaiting)
+ {
+ synchronized (waiting)
+ {
+ waiting.remove(miTx);
+ }
+ }
+ }
// If we get here, this means that we have the txlock
this.tx = miTx;
@@ -444,5 +470,6 @@
System.out.println(Thread.currentThread() + " removing lock!");
*/
}
+
}
1.10 +31 -1 jboss/src/main/org/jboss/ejb/plugins/lock/BeanLockSupport.java
Index: BeanLockSupport.java
===================================================================
RCS file:
/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/lock/BeanLockSupport.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- BeanLockSupport.java 2001/12/19 06:04:48 1.9
+++ BeanLockSupport.java 2002/01/12 20:21:07 1.10
@@ -15,6 +15,8 @@
import org.jboss.ejb.BeanLock;
import org.jboss.invocation.Invocation;
import org.jboss.logging.Logger;
+import java.util.HashMap;
+import java.util.HashSet;
/**
@@ -22,7 +24,7 @@
*
* @author <a href="[EMAIL PROTECTED]">Bill Burke</a>
* @author <a href="[EMAIL PROTECTED]">Marc Fleury</a>
- * @version $Revision: 1.9 $
+ * @version $Revision: 1.10 $
*
* <p><b>Revisions:</b><br>
* <p><b>2001/07/29: marcf</b>
@@ -164,5 +166,33 @@
}
return false;
+ }
+
+ // This following is for deadlock detection
+ protected static HashMap waiting = new HashMap();
+
+ public void deadlockDetection(Transaction miTx)
+ {
+ HashSet set = new HashSet();
+ set.add(miTx);
+
+ Object checkTx = this.tx;
+ synchronized(waiting)
+ {
+ while (checkTx != null)
+ {
+ Object waitingFor = waiting.get(checkTx);
+ if (waitingFor != null)
+ {
+ if (set.contains(waitingFor))
+ {
+ log.error("Application deadlock detected: " + miTx + " has deadlock
conditions");
+ throw new RuntimeException("application deadlock detected");
+ }
+ set.add(waitingFor);
+ }
+ checkTx = waitingFor;
+ }
+ }
}
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development