svn commit: r536705 - /ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/GenericXaResource.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r536705 - /ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/GenericXaResource.java

jaz-3
Author: jaz
Date: Wed May  9 15:57:40 2007
New Revision: 536705

URL: http://svn.apache.org/viewvc?view=rev&rev=536705
Log:
added tracer to internal XAResource to notify when transactions timeout

Modified:
    ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/GenericXaResource.java

Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/GenericXaResource.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/GenericXaResource.java?view=diff&rev=536705&r1=536704&r2=536705
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/GenericXaResource.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/GenericXaResource.java Wed May  9 15:57:40 2007
@@ -28,12 +28,12 @@
 /**
  * GenericXaResource - Abstract XA Resource implementation supporting a single transaction
  */
-public abstract class GenericXaResource implements XAResource {
+public abstract class GenericXaResource extends Thread implements XAResource {
 
     public static final String module = GenericXaResource.class.getName();
 
     protected boolean active = false;
-    protected int timeout = 0;
+    protected int timeout = 30;
     protected Xid xid = null;
 
     /**
@@ -75,8 +75,11 @@
             throw new XAException(XAException.XAER_NOTA);
         }
 
-        this.xid = xid;
+        this.setName("GenericXaResource-Thread");
+        this.setDaemon(true);
         this.active = true;
+        this.xid = xid;        
+        this.start();
     }
 
     /**
@@ -147,7 +150,7 @@
      * Note: the valus is saved but in the current implementation this is not used.
      */
     public boolean setTransactionTimeout(int seconds) throws XAException {
-        this.timeout = seconds;
+        this.timeout = seconds == 0 ? 30 : seconds;
         return true;
     }
 
@@ -164,4 +167,37 @@
      * @see javax.transaction.xa.XAResource#rollback(javax.transaction.xa.Xid xid)
      */
     public abstract void rollback(Xid xid) throws XAException;
+
+    /**
+     * Method which will run when the transaction times out
+     */
+    public void runOnTimeout() {
+    }
+
+    // thread run method
+    public void run() {
+        try {
+            // sleep until the transaction times out
+            sleep(timeout * 1000);
+
+            if (active) {
+                // get the current status
+                int status = Status.STATUS_UNKNOWN;
+                try {
+                    status = TransactionUtil.getStatus();
+                } catch (GenericTransactionException e) {
+                    Debug.logWarning(e, module);
+                }
+
+                // log a warning message
+                String statusString = TransactionUtil.getTransactionStateString(status);
+                Debug.logWarning("Transaction timeout [" + timeout + "] Status: " + statusString + " Xid: " + getXid(), module);
+
+                // run the abstract method
+                runOnTimeout();
+            }
+        } catch (InterruptedException e) {
+            Debug.logWarning(e, "InterruptedException thrown", module);
+        }
+    }
 }


Reply | Threaded
Open this post in threaded view
|

Re: svn commit: r536705 - /ofbiz/trunk/framework/entity/src/org/ofbiz/entity/transaction/GenericXaResource.java

Markus B.
This change is actually pretty dangerous and should seriuosly be reconsidered (eventhough it is 5 years ago). It results in a new thread started for each new transaction which sleeps for the defined timeout duration just for the purpose of logging a timed out transaction (note that all read-only delegator methods like e.g. findByPrimaryKey start a new transaction as well). Even worse: If the transaction is finished before the timeout the thread keeps sleeping and is not interrupted until the timeout threshold is reached.

Now keep in mind that the number of threads you can create is very limited under certain circumstances (see: http://blog.egilh.com/2006/06/2811aspx.html).  

We have a custom web apllication based on OFBiz 9.0.4. In practive we have faced a situation where on a 32 bit machine the JobPoller threw countless OutOfMemoryErrors complaining that it was unable to create a native thread. Our analysis showed that the system was capable of handling about 1000 threads. 10 Users working parallely (invoking services that utilize the framework's delegator methods), a transaction timeout of 60 seconds and a handful of scheduled jobs were enough to kill the system just because of the huge amount of "GenericXaResource-Thread"s being started (again: only for the purpose of logging). Without starting a thread for each transaction everything is fine again now. But it took us about a week to identify GenericXaResource as the cause of the problem.

Regards
Markus