]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
switched objectstore begin/commit behavior to do "reentrant counter"
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 3 Feb 2006 00:42:22 +0000 (00:42 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 3 Feb 2006 00:42:22 +0000 (00:42 +0000)
doc/build/content/unitofwork.myt
lib/sqlalchemy/mapping/objectstore.py

index d3ddb2b366a3e8690e6e4c5ada5c62b2dcb555cc..83f78e804b19de92e004136a0fe91c0bf84a826b 100644 (file)
         objectstore.commit()
     </&>
     <p>As always, the actual database transaction begin/commit occurs entirely within the objectstore.commit() operation.</p>
-    
-    <p>Since the begin/commit paradigm works in a stack-based manner, it follows that any level of nesting of begin/commit can be used:</p>
-    <&|formatting.myt:code&>
-        # start with UOW #1 as the thread-local UnitOfWork
-        a = Foo()
-        objectstore.begin()  # push UOW #2 on the stack
-        b = Foo()
-        objectstore.begin()  # push UOW #3 on the stack
-        c = Foo()
-
-        # saves 'c'
-        objectstore.commit() # commit UOW #3
-
-        d = Foo()
-
-        # saves 'b' and 'd'
-        objectstore.commit() # commit UOW #2
-        
-        # saves 'a', everything else prior to it
-        objectstore.commit() # commit thread-local UOW #1
-    </&>
+    <p>At the moment, begin/commit supports the same "nesting" behavior as the SQLEngine (note this behavior is not the original "nested" behavior), meaning that repeated calls to begin() will increment a counter, which is not released until that same number of commit() statements occur.</p>
     </&>
     <&|doclib.myt:item, name="transactionnesting", description="Nesting UnitOfWork in a Database Transaction" &>
     <p>The UOW commit operation places its INSERT/UPDATE/DELETE operations within the scope of a database transaction controlled by a SQLEngine:
index f4775f95efef7ba1f07fb262d835da0c83b2dd3f..23b98f42ed4880ca1353161fe6c1829a9f81783a 100644 (file)
@@ -149,6 +149,10 @@ class UOWAttributeManager(attributes.AttributeManager):
 class UnitOfWork(object):
     def __init__(self, parent = None, is_begun = False):
         self.is_begun = is_begun
+        if is_begun:
+            self.begin_count = 1
+        else:
+            self.begin_count = 0
         if parent is not None:
             self.identity_map = parent.identity_map
         else:
@@ -245,10 +249,17 @@ class UnitOfWork(object):
             
     # TODO: tie in register_new/register_dirty with table transaction begins ?
     def begin(self):
+        if self.is_begun:
+            self.begin_count += 1
+            return
         u = UnitOfWork(self, True)
         uow.set(u)
         
     def commit(self, *objects):
+        if self.is_begun:
+            self.begin_count -= 1
+            if self.begin_count > 0:
+                return
         commit_context = UOWTransaction(self)
 
         if len(objects):
@@ -312,10 +323,9 @@ class UnitOfWork(object):
     def rollback(self):
         if not self.is_begun:
             raise "UOW transaction is not begun"
-        # TODO: locate only objects that are dirty/new/deleted in this UOW,
-        # roll only those back.
-        for obj in self.deleted + self.dirty + self.new:
-            self.attributes.rollback(obj)
+        # roll back attributes ?  nah....
+        #for obj in self.deleted + self.dirty + self.new:
+        #    self.attributes.rollback(obj)
         uow.set(self.parent)
             
 class UOWTransaction(object):