This is an automated email from the ASF dual-hosted git repository.

doebele pushed a commit to branch version3
in repository https://gitbox.apache.org/repos/asf/empire-db.git


The following commit(s) were added to refs/heads/version3 by this push:
     new d386335  EMPIREDB-364 Improved rollback handling
d386335 is described below

commit d3863352bebb7319b84d157a72be9cc0a80dafc8
Author: Rainer Döbele <[email protected]>
AuthorDate: Wed Feb 9 12:35:47 2022 +0100

    EMPIREDB-364 Improved rollback handling
---
 .../jsf2/websample/web/SampleApplication.java      | 22 +++++++++++----
 .../org/apache/empire/jsf2/app/WebApplication.java | 32 ++++++++++------------
 .../java/org/apache/empire/db/DBRecordBase.java    |  5 ++--
 .../apache/empire/db/context/DBContextBase.java    | 10 +++----
 .../empire/db/context/DBRollbackHandler.java       |  6 ++--
 .../empire/db/context/DBRollbackManager.java       |  6 ++--
 6 files changed, 45 insertions(+), 36 deletions(-)

diff --git 
a/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/web/SampleApplication.java
 
b/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/web/SampleApplication.java
index 6784155..25e3921 100644
--- 
a/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/web/SampleApplication.java
+++ 
b/empire-db-examples/empire-db-example-jsf2/src/main/java/org/apache/empire/jsf2/websample/web/SampleApplication.java
@@ -33,6 +33,8 @@ import org.apache.empire.db.DBDatabase;
 import org.apache.empire.db.DBRecord;
 import org.apache.empire.db.DBSQLScript;
 import org.apache.empire.db.context.DBContextStatic;
+import org.apache.empire.db.context.DBRollbackManager;
+import org.apache.empire.db.context.DBRollbackManager.ReleaseAction;
 import org.apache.empire.db.exceptions.QueryFailedException;
 import org.apache.empire.dbms.DBMSHandler;
 import org.apache.empire.dbms.hsql.DBMSHandlerHSql;
@@ -139,7 +141,7 @@ public class SampleApplication extends WebApplication {
                DBContext context = null;
                try {
                        conn = getConnection(sampleDB);
-                       context = new DBContextStatic(dbmsHandler, conn);
+                       context = new DBContextStatic(dbmsHandler, conn, false, 
false);
                        sampleDB.open(context);
                        if (!databaseExists(context)) {
                                // STEP 4: Create Database
@@ -148,7 +150,7 @@ public class SampleApplication extends WebApplication {
                        }
                } finally {
                    context.discard();
-                       releaseConnection(sampleDB, conn, true);
+                       releaseConnection(conn, true, null);
                }
        }
 
@@ -295,7 +297,7 @@ public class SampleApplication extends WebApplication {
      * As the sample does not use connection pooling, only a commit or 
rollback is performed
      */
     @Override
-    protected void releaseConnection(DBDatabase db, Connection conn, boolean 
commit)
+    protected void releaseConnection(Connection conn, boolean commit, 
DBRollbackManager dbrm)
     {
         try
         { // release connection
@@ -303,19 +305,27 @@ public class SampleApplication extends WebApplication {
             {
                 return;
             }
+            log.trace("releasing Connection {}", conn.hashCode());
             // Commit or rollback connection depending on the exit code
             if (commit)
-            { // success: commit all changes
+            {   // success: commit all changes
+                if (dbrm!=null)
+                    dbrm.releaseConnection(conn, ReleaseAction.Discard);  // 
before commit
                 conn.commit();
                 log.debug("REQUEST commited.");
             }
             else
-            { // failure: rollback all changes
+            {   // failure: rollback all changes
                 conn.rollback();
+                if (dbrm!=null)
+                    dbrm.releaseConnection(conn, ReleaseAction.Rollback); // 
after rollback
                 log.debug("REQUEST rolled back.");
             }
-            // Don't Release Connection
+            // Release Connection (don't do that here!)
             // conn.close();
+            // done
+            if (log.isDebugEnabled())
+                log.debug("Connection released but not closed.");
         }
         catch (SQLException e)
         {
diff --git 
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/WebApplication.java 
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/WebApplication.java
index 306cdbd..2d1b557 100644
--- 
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/WebApplication.java
+++ 
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/app/WebApplication.java
@@ -429,24 +429,27 @@ public abstract class WebApplication
     /**
      * Releases a JDBC-Connection from the connection pool
      */
-    protected synchronized void releaseConnection(DBDatabase db, Connection 
conn, boolean commit)
+    protected synchronized void releaseConnection(Connection conn, boolean 
commit, DBRollbackManager dbrm)
     {
         try
-        { // release connection
+        {   // check
             if (conn == null)
-            {
                 return;
-            }
+            // release connection
             log.trace("releasing Connection {}", conn.hashCode());
             // Commit or rollback connection depending on the exit code
             if (commit)
-            { // success: commit all changes
+            {   // success: commit all changes
+                if (dbrm!=null)
+                    dbrm.releaseConnection(conn, ReleaseAction.Discard);  // 
before commit
                 conn.commit();
                 log.debug("REQUEST commited.");
             }
             else
-            { // failure: rollback all changes
+            {   // failure: rollback all changes
                 conn.rollback();
+                if (dbrm!=null)
+                    dbrm.releaseConnection(conn, ReleaseAction.Rollback); // 
after rollback
                 log.debug("REQUEST rolled back.");
             }
             // Release Connection
@@ -526,14 +529,9 @@ public abstract class WebApplication
             return; // Nothing to do
         // Walk the connection map
         DBRollbackManager dbrm = getRollbackManagerForRequest(fc, false);
-        ReleaseAction action = (commit ? ReleaseAction.Discard : 
ReleaseAction.Rollback);
-        for (Map.Entry<DBDatabase, Connection> e : connMap.entrySet())
+        for (Connection conn : connMap.values())
         {
-            Connection conn = e.getValue();
-            releaseConnection(e.getKey(), conn, commit);
-            // release connection
-            if (dbrm!=null)
-                dbrm.releaseConnection(conn, action);
+            releaseConnection(conn, commit, dbrm);
         }
         // remove from request map
         FacesUtils.setRequestAttribute(fc, REQUEST_CONNECTION_MAP, null);
@@ -561,13 +559,11 @@ public abstract class WebApplication
         Map<DBDatabase, Connection> connMap = (Map<DBDatabase, Connection>) 
FacesUtils.getRequestAttribute(fc, REQUEST_CONNECTION_MAP);
         if (connMap == null || !connMap.containsKey(db))
             return; // Nothing to do;
+        // Get RollbackManager   
+        DBRollbackManager dbrm = getRollbackManagerForRequest(fc, false);
         // Release Connection   
         Connection conn = connMap.get(db);
-        releaseConnection(db, conn, commit);
-        // release connection
-        DBRollbackManager dbrm = getRollbackManagerForRequest(fc, false);
-        if (dbrm!=null)
-            dbrm.releaseConnection(conn, (commit ? ReleaseAction.Discard : 
ReleaseAction.Rollback));
+        releaseConnection(conn, commit, dbrm);
         // Remove from map
         connMap.remove(db);
     }
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java 
b/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
index 7a68e1e..692eb4b 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
@@ -19,6 +19,7 @@
 package org.apache.empire.db;
 
 import java.lang.reflect.InvocationTargetException;
+import java.sql.Connection;
 import java.util.Collection;
 import java.util.List;
 
@@ -134,7 +135,7 @@ public abstract class DBRecordBase extends DBRecordData 
implements Record, Clone
         }
 
         @Override
-        public void rollback()
+        public void rollback(Connection conn)
         {
             // rollback
             record.state = this.state;
@@ -147,7 +148,7 @@ public abstract class DBRecordBase extends DBRecordData 
implements Record, Clone
         }
 
         @Override
-        public void discard()
+        public void discard(Connection conn)
         {
             /* nothing */
         }
diff --git 
a/empire-db/src/main/java/org/apache/empire/db/context/DBContextBase.java 
b/empire-db/src/main/java/org/apache/empire/db/context/DBContextBase.java
index fdff5a5..c03464c 100644
--- a/empire-db/src/main/java/org/apache/empire/db/context/DBContextBase.java
+++ b/empire-db/src/main/java/org/apache/empire/db/context/DBContextBase.java
@@ -158,13 +158,13 @@ public abstract class DBContextBase implements DBContext
             {   log.info("No Connection to commmit changes");
                 return; // Nothing to do
             }
-            // Commit
-            if (conn.getAutoCommit()==false)
-                conn.commit();
-            // discard rollbacks
+            // Perform Discard before commit
             DBRollbackManager dbrm = (isRollbackHandlingEnabled() ? 
getRollbackManager(false) : null);
             if (dbrm!=null)
                 dbrm.releaseConnection(conn, ReleaseAction.Discard);
+            // Commit
+            if (conn.getAutoCommit()==false)
+                conn.commit();
             // Done
             return;
         } catch (SQLException sqle) { 
@@ -193,7 +193,7 @@ public abstract class DBContextBase implements DBContext
             // rollback
             log.info("Database rollback issued!");
             conn.rollback();
-            // perform Rollback
+            // Perform Rollback
             DBRollbackManager dbrm = (isRollbackHandlingEnabled() ? 
getRollbackManager(false) : null);
             if (dbrm!=null)
                 dbrm.releaseConnection(conn, ReleaseAction.Rollback);
diff --git 
a/empire-db/src/main/java/org/apache/empire/db/context/DBRollbackHandler.java 
b/empire-db/src/main/java/org/apache/empire/db/context/DBRollbackHandler.java
index 72ded99..a03719c 100644
--- 
a/empire-db/src/main/java/org/apache/empire/db/context/DBRollbackHandler.java
+++ 
b/empire-db/src/main/java/org/apache/empire/db/context/DBRollbackHandler.java
@@ -18,6 +18,8 @@
  */
 package org.apache.empire.db.context;
 
+import java.sql.Connection;
+
 import org.apache.empire.db.DBObject;
 
 public interface DBRollbackHandler
@@ -25,6 +27,6 @@ public interface DBRollbackHandler
     DBObject getObject();
     String getObjectInfo();
     void combine(DBRollbackHandler successor);
-    void rollback();
-    void discard();
+    void rollback(Connection conn);
+    void discard(Connection conn);
 }
diff --git 
a/empire-db/src/main/java/org/apache/empire/db/context/DBRollbackManager.java 
b/empire-db/src/main/java/org/apache/empire/db/context/DBRollbackManager.java
index 49d36a9..b8c1d68 100644
--- 
a/empire-db/src/main/java/org/apache/empire/db/context/DBRollbackManager.java
+++ 
b/empire-db/src/main/java/org/apache/empire/db/context/DBRollbackManager.java
@@ -108,7 +108,7 @@ public class DBRollbackManager
         // discard
         if (log.isDebugEnabled())
             log.debug("Rollback handler for {} was removed.", 
handler.getObjectInfo());
-        handler.discard();
+        handler.discard(conn);
     }
     
     /**
@@ -127,9 +127,9 @@ public class DBRollbackManager
         log.info("DBRollbackManager performes {} for {} objects.", action, 
handlerMap.size());
         for (DBRollbackHandler handler : handlerMap.values())
             if (action==ReleaseAction.Rollback)
-                handler.rollback();
+                handler.rollback(conn);
             else
-                handler.discard();
+                handler.discard(conn);
         // cleanup
         connectionMap.remove(conn.hashCode());        
     }

Reply via email to