[Top][All Lists]
[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)
# ---------------------------------------------------------------------------
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r7984 - trunk/gnue-appserver/src,
reinhard <=