commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnue] r7984 - trunk/gnue-appserver/src


From: reinhard
Subject: [gnue] r7984 - trunk/gnue-appserver/src
Date: Wed, 28 Sep 2005 12:35:41 -0500 (CDT)

Author: reinhard
Date: 2005-09-24 04:55:27 -0500 (Sat, 24 Sep 2005)
New Revision: 7984

Modified:
   trunk/gnue-appserver/src/data.py
Log:
When an exception happens when writing data to the backend, rollback the
transaction if required.


Modified: trunk/gnue-appserver/src/data.py
===================================================================
--- trunk/gnue-appserver/src/data.py    2005-09-24 09:52:49 UTC (rev 7983)
+++ trunk/gnue-appserver/src/data.py    2005-09-24 09:55:27 UTC (rev 7984)
@@ -530,9 +530,10 @@
       self.__old.clear ()
       self.__new.clear ()
       self.__state.clear ()
+      self.inserted.clear ()
+      self.deleted.clear ()
 
 
-
   # ---------------------------------------------------------------------------
   # Make the given row in a table to be treated as 'clean'
   # ---------------------------------------------------------------------------
@@ -931,38 +932,60 @@
 
     tables = self.__cache.dirtyTables ()
 
-    backend = self.__backend
+    # We distinguish 2 cases here:
+    # A: Backend knows transactions and needs a rollback when an exception has
+    # happened: we send all changes to the backend and leave the cache
+    # unchanged until the commit has succeeded, so we can restore to the state
+    # before in case of an exception. With this case, we will never have any
+    # uncommitted changes hanging around in the backend.
+    # B: Backend does not know transactions or does not need a rollback when an
+    # exception has happened: we clean up each single change from the cache as
+    # soon as we have sent it to the backend, so in case of an exception we can
+    # later continue where we've stopped. With this case, some changes at the
+    # backend might remain uncommitted until the commit is tried again without
+    # exception.
 
-    # first perform all inserts
-    if self.__cache.inserted:
-      for (table, row) in self.__orderInserts ():
-        fields = tables [table] [row]
+    try:
+      # first perform all inserts
+      if self.__cache.inserted:
+        for (table, row) in self.__orderInserts ():
+          fields = tables [table] [row]
+          self.__backend.insert (table, fields)
+          if not self.__backend._need_rollback_after_exception_:
+            self.__cache.makeClean (table, row)
 
-        backend.insert (table, fields)
-        self.__cache.makeClean (table, row)
+      # second perform all updates
+      for (table, rows) in tables.items ():
+        for (row, fields) in rows.items ():
+          if self.__cache.state (table, row) == 'changed':
+            self.__backend.update (table, {'gnue_id': row}, fields)
+            if not self.__backend._need_rollback_after_exception_:
+              self.__cache.makeClean (table, row)
 
+      # perform all deletes
+      if len (self.__cache.deleted):
+        for (table, row) in self.__orderDeletes ():
+          self.__backend.delete (table, {'gnue_id': row})
+          if not self.__backend._need_rollback_after_exception_:
+            self.__cache.remove (table, row)
 
-    # second perform all updates
-    for (table, rows) in tables.items ():
-      for (row, fields) in rows.items ():
-        if self.__cache.state (table, row) == 'changed':
-          backend.update (table, {'gnue_id': row}, fields)
-          self.__cache.makeClean (table, row)
+      # Commit the whole transaction
+      self.__backend.commit ()
 
+    except:
+      if self.__backend._need_rollback_after_exception_:
+        self.__backend.rollback ()
+      raise
 
-    # perform all deletes
-    if len (self.__cache.deleted):
-      for (table, row) in self.__orderDeletes ():
-        backend.delete (table, {'gnue_id': row})
-        self.__cache.remove (table, row)
-
-
-    # Commit the whole transaction
-    self.__backend.commit ()
-
     # The transaction has ended. Changes from other transactions could become
     # valid in this moment, so we have to clear the cache.
-    self.__cache.clear (True)
+    if self.__backend._need_rollback_after_exception_:
+      self.__cache.clear ()
+    else:
+      # FIXME: I'm not sure if it makes sense to clean "only old" data here. In
+      # which cases will there be something left in the "new" cache? I mean, we
+      # just committed all changes, didn't we??  -- Reinhard
+      self.__cache.clear (True)
 
 
   # ---------------------------------------------------------------------------





reply via email to

[Prev in Thread] Current Thread [Next in Thread]