[ZODB-Dev] Commit or lock object accross transactions

Roché Compaan roche at upfrontsystems.co.za
Thu Aug 7 19:17:33 EDT 2003


* Roché Compaan <roche at upfrontsystems.co.za> [2003-08-07 08:14]:
> > Could you produce a diff -u so we can take a look at the code? A
> > testcase would be doubly appreciated, so if you can attach a simple one,
> > it would be even better.
> 
> 
> Here u go:
> 

Didn't include the changes to ServerStub.py, so here we go again, this
time as attachment.

-- 
Roché Compaan
Upfront Systems                 http://www.upfrontsystems.co.za
-------------- next part --------------
Index: ZEO/ClientStorage.py
===================================================================
RCS file: /cvs-repository/ZODB3/ZEO/ClientStorage.py,v
retrieving revision 1.108
diff -u -r1.108 ClientStorage.py
--- ZEO/ClientStorage.py	6 Aug 2003 15:51:23 -0000	1.108
+++ ZEO/ClientStorage.py	7 Aug 2003 16:13:38 -0000
@@ -776,6 +776,28 @@
         finally:
             self._oid_lock.release()
 
+    def get_id_block(self, key):
+        if not hasattr(self, '_id_blocks'):
+            self._id_blocks = {}
+        if not self._id_blocks.has_key(key):
+            self._id_blocks[key] = []
+        return self._id_blocks[key]
+
+    def generate_id(self, key=""):
+        """return the next id in a sequence for a given key."""
+        if self._is_read_only:
+            raise POSException.ReadOnlyError()
+        # avoid multiple id requests to server at the same time
+        self._oid_lock.acquire()
+        try:
+            block = self.get_id_block(key)
+            if not block:
+                self._id_blocks[key] = self._server.generate_ids(key)
+                self._id_blocks[key].reverse()
+            return self._id_blocks[key].pop()
+        finally:
+            self._oid_lock.release()
+
     def pack(self, t=None, referencesf=None, wait=1, days=0):
         """Storage API: pack the storage.
 
Index: ZEO/ServerStub.py
===================================================================
RCS file: /cvs-repository/ZODB3/ZEO/ServerStub.py,v
retrieving revision 1.16
diff -u -r1.16 ServerStub.py
--- ZEO/ServerStub.py	30 May 2003 19:20:57 -0000	1.16
+++ ZEO/ServerStub.py	7 Aug 2003 16:13:44 -0000
@@ -68,6 +68,12 @@
         else:
             return self.rpc.call('new_oids', n)
 
+    def generate_ids(self, key, n=None):
+        if n is None:
+            return self.rpc.call('generate_ids', key)
+        else:
+            return self.rpc.call('generate_ids', key, n)
+
     def pack(self, t, wait=None):
         if wait is None:
             self.rpc.call('pack', t)
Index: ZEO/StorageServer.py
===================================================================
RCS file: /cvs-repository/ZODB3/ZEO/StorageServer.py,v
retrieving revision 1.98
diff -u -r1.98 StorageServer.py
--- ZEO/StorageServer.py	13 Jun 2003 19:50:05 -0000	1.98
+++ ZEO/StorageServer.py	7 Aug 2003 16:13:53 -0000
@@ -327,6 +327,16 @@
             n = 1
         return [self.storage.new_oid() for i in range(n)]
 
+    def generate_ids(self, key="", n=100):
+        """ Return a sequence of n new ids for 'key', where n
+            defaults to 100
+        """
+        if self.read_only:
+            raise ReadOnlyError()
+        if n <= 0:
+            n = 1
+        return [self.storage.generate_id(key) for i in range(n)]
+
     def undo(self, transaction_id):
         if self.read_only:
             raise ReadOnlyError()
Index: ZODB/BaseStorage.py
===================================================================
RCS file: /cvs-repository/ZODB3/ZODB/BaseStorage.py,v
retrieving revision 1.34
diff -u -r1.34 BaseStorage.py
--- ZODB/BaseStorage.py	10 Jun 2003 15:46:31 -0000	1.34
+++ ZODB/BaseStorage.py	7 Aug 2003 16:13:55 -0000
@@ -47,6 +47,7 @@
             self._oid='\0\0\0\0\0\0\0\0'
         else:
             self._oid=base._oid
+        self._counters = {}
 
     def abortVersion(self, src, transaction):
         if transaction is not self._transaction:
@@ -100,6 +101,24 @@
             d=ord(last[-1])
             if d < 255: return last[:-1]+chr(d+1)+'\0'*(8-len(last))
             else:       return self.new_oid(last[:-1])
+
+    def getCounter(self, key):
+        if not hasattr(self, '_counters'):
+            self._counters = {}
+        if not self._counters.has_key(key):
+            self._counters[key] = 0
+        return self._counters[key]
+
+    def generate_id(self, key=""):
+        if self._is_read_only:
+            raise POSException.ReadOnlyError()
+        self._lock_acquire()
+        try:
+            count = self.getCounter(key) + 1
+            self._counters[key] = count
+            return count
+        finally:
+            self._lock_release()
 
     def registerDB(self, db, limit):
         pass # we don't care
Index: ZODB/Connection.py
===================================================================
RCS file: /cvs-repository/ZODB3/ZODB/Connection.py,v
retrieving revision 1.98
diff -u -r1.98 Connection.py
--- ZODB/Connection.py	13 Jun 2003 21:53:08 -0000	1.98
+++ ZODB/Connection.py	7 Aug 2003 16:14:02 -0000
@@ -233,6 +233,7 @@
         self._storage=s=odb._storage
         self._sortKey = odb._storage.sortKey
         self.new_oid=s.new_oid
+        self.generate_id=getattr(s, 'generate_id', None)
         if self._code_timestamp != global_code_timestamp:
             # New code is in place.  Start a new cache.
             self._resetCache()
@@ -290,7 +291,8 @@
                     LOG('ZODB',ERROR, 'Close callback failed for %s' % f,
                         error=sys.exc_info())
             self.__onCloseCallbacks = None
-        self._storage = self._tmp = self.new_oid = self._opened = None
+        self._storage = self._tmp = self.new_oid = self._opened = \
+            self.generate_id = None
         self._debug_info = ()
         # Return the connection to the pool.
         self._db._closeConnection(self)


More information about the ZODB-Dev mailing list