[Checkins] SVN: relstorage/trunk/ Made compatible with ZODB 3.10 and fixed a MySQL deadlock caused by somebody changing the default transaction isolation mode.
Shane Hathaway
shane at hathawaymix.org
Sat Jun 19 18:01:34 EDT 2010
Log message for revision 113702:
Made compatible with ZODB 3.10 and fixed a MySQL deadlock caused by somebody changing the default transaction isolation mode.
Changed:
U relstorage/trunk/CHANGES.txt
U relstorage/trunk/README.txt
U relstorage/trunk/buildout.cfg
U relstorage/trunk/relstorage/__init__.py
U relstorage/trunk/relstorage/adapters/mysql.py
U relstorage/trunk/relstorage/options.py
U relstorage/trunk/relstorage/storage.py
U relstorage/trunk/relstorage/tests/RecoveryStorage.py
U relstorage/trunk/setup.py
-=-
Modified: relstorage/trunk/CHANGES.txt
===================================================================
--- relstorage/trunk/CHANGES.txt 2010-06-19 19:27:28 UTC (rev 113701)
+++ relstorage/trunk/CHANGES.txt 2010-06-19 22:01:34 UTC (rev 113702)
@@ -2,12 +2,27 @@
------------
- History-preserving storages now replace objects on restore instead of
- just inserting them.
+ just inserting them. This should solve problems people were
+ having with the zodbconvert utility.
- Oracle: call the DBMS_LOCK.REQUEST function directly instead of using
- a small package. The small relstorage_util package was confusing to DBAs
- and provided no real security advantage.
+ a small package named ``relstorage_util``. The ``relstorage_util``
+ package was designed as a secure way to access the DBMS_LOCK package,
+ but the package turned out to be confusing to DBAs and provided no
+ real security advantage. Existing deployments of RelStorage 1.4.x on
+ Oracle need to do the following:
+ GRANT EXECUTE ON DBMS_LOCK TO <zodb_user>;
+
+ You can also drop the ``relstorage_util`` package (but keep the
+ ``relstorage_op`` package).
+
+- Made compatible with ZODB 3.10.
+
+- MySQL: specify the transaction isolation mode for every connection,
+ since the default is apparently not necessarily "read committed"
+ anymore.
+
1.4.0b3 (2010-02-02)
--------------------
Modified: relstorage/trunk/README.txt
===================================================================
--- relstorage/trunk/README.txt 2010-06-19 19:27:28 UTC (rev 113701)
+++ relstorage/trunk/README.txt 2010-06-19 22:01:34 UTC (rev 113702)
@@ -119,7 +119,8 @@
You need to create a database user and grant execute privileges on
the DBMS_LOCK package to that user.
-Here are some sample SQL statements for creating the database user::
+Here are some sample SQL statements for creating the database user
+and granting the required permissions::
CREATE USER zodb IDENTIFIED BY mypassword;
GRANT CONNECT, RESOURCE, CREATE TABLE, CREATE SEQUENCE TO zodb;
@@ -476,7 +477,8 @@
RelStorage caches pickled objects in memory, similar to a ZEO
cache. This cache is shared between threads. This parameter
configures the approximate maximum amount of memory the cache
- should consume, in megabytes. It defaults to 10.
+ should consume, in megabytes. It defaults to 10. Set to
+ 0 to disable the in-memory cache.
``cache-delta-size-limit``
This is an advanced option. RelStorage uses a system of
Modified: relstorage/trunk/buildout.cfg
===================================================================
--- relstorage/trunk/buildout.cfg 2010-06-19 19:27:28 UTC (rev 113701)
+++ relstorage/trunk/buildout.cfg 2010-06-19 22:01:34 UTC (rev 113702)
@@ -5,7 +5,7 @@
eggs = relstorage
psycopg2
MySQL-python
- ZODB3<3.10.0a1
+ ZODB3 [test]
[test]
recipe = zc.recipe.testrunner
Modified: relstorage/trunk/relstorage/__init__.py
===================================================================
--- relstorage/trunk/relstorage/__init__.py 2010-06-19 19:27:28 UTC (rev 113701)
+++ relstorage/trunk/relstorage/__init__.py 2010-06-19 22:01:34 UTC (rev 113702)
@@ -13,18 +13,18 @@
##############################################################################
"""relstorage package"""
-# perform a compatibility test
-try:
- from ZODB.interfaces import IMVCCStorage
- del IMVCCStorage
-except ImportError:
- # see if the polling patch has been applied
- from ZODB.Connection import Connection
- if not hasattr(Connection, '_poll_invalidations'):
- raise ImportError('RelStorage requires the invalidation polling '
- 'patch for ZODB.')
- del Connection
-else:
- # We're running a version of ZODB that knows what to do with
- # MVCC storages, so no patch is necessary.
- pass
+def check_compatible():
+ try:
+ from ZODB.interfaces import IMVCCStorage
+ except ImportError:
+ # see if the polling patch has been applied
+ from ZODB.Connection import Connection
+ if not hasattr(Connection, '_poll_invalidations'):
+ raise ImportError('RelStorage requires the invalidation polling '
+ 'patch for ZODB.')
+ else:
+ # We're running a version of ZODB that knows what to do with
+ # MVCC storages, so no patch is necessary.
+ pass
+
+check_compatible()
Modified: relstorage/trunk/relstorage/adapters/mysql.py
===================================================================
--- relstorage/trunk/relstorage/adapters/mysql.py 2010-06-19 19:27:28 UTC (rev 113701)
+++ relstorage/trunk/relstorage/adapters/mysql.py 2010-06-19 22:01:34 UTC (rev 113702)
@@ -251,7 +251,7 @@
This overrides a method.
"""
- conn, cursor = self.open(transaction_mode=None)
+ conn, cursor = self.open()
try:
# This phase of packing works best with transactions
# disabled. It changes no user-facing data.
Modified: relstorage/trunk/relstorage/options.py
===================================================================
--- relstorage/trunk/relstorage/options.py 2010-06-19 19:27:28 UTC (rev 113701)
+++ relstorage/trunk/relstorage/options.py 2010-06-19 22:01:34 UTC (rev 113702)
@@ -12,6 +12,7 @@
#
##############################################################################
+
class Options(object):
"""Options for configuring and tuning RelStorage.
@@ -43,9 +44,21 @@
self.cache_delta_size_limit = 10000
self.commit_lock_timeout = 30
self.commit_lock_id = 0
+ self.strict_tpc = default_strict_tpc
for key, value in kwoptions.iteritems():
if key in self.__dict__:
setattr(self, key, value)
else:
raise TypeError("Unknown parameter: %s" % key)
+
+
+# Detect the version of ZODB and set default options accordingly.
+# ZODB does not seem to provide version information anywhere but in
+# setup.py, so the code below is a hack. TODO: Bring this up on zodb-dev.
+
+default_strict_tpc = False
+
+from ZEO.zrpc.connection import Connection as __Connection
+if __Connection.current_protocol >= 'Z310':
+ default_strict_tpc = True
Modified: relstorage/trunk/relstorage/storage.py
===================================================================
--- relstorage/trunk/relstorage/storage.py 2010-06-19 19:27:28 UTC (rev 113701)
+++ relstorage/trunk/relstorage/storage.py 2010-06-19 22:01:34 UTC (rev 113702)
@@ -614,6 +614,9 @@
self._lock_acquire()
try:
if self._transaction is transaction:
+ if self._options.strict_tpc:
+ raise POSException.StorageTransactionError(
+ "Duplicate tpc_begin calls for same transaction")
return
self._lock_release()
self._commit_lock_acquire()
@@ -759,6 +762,9 @@
self._lock_acquire()
try:
if transaction is not self._transaction:
+ if self._options.strict_tpc:
+ raise POSException.StorageTransactionError(
+ "tpc_vote called with wrong transaction")
return
try:
return self._vote()
@@ -819,6 +825,9 @@
self._lock_acquire()
try:
if transaction is not self._transaction:
+ if self._options.strict_tpc:
+ raise POSException.StorageTransactionError(
+ "tpc_finish called with wrong transaction")
return
try:
try:
Modified: relstorage/trunk/relstorage/tests/RecoveryStorage.py
===================================================================
--- relstorage/trunk/relstorage/tests/RecoveryStorage.py 2010-06-19 19:27:28 UTC (rev 113701)
+++ relstorage/trunk/relstorage/tests/RecoveryStorage.py 2010-06-19 22:01:34 UTC (rev 113702)
@@ -89,8 +89,20 @@
# Make sure ther are no more records left in txn1 and txn2, meaning
# they were the same length
- self.assertRaises(IndexError, iter1.next)
- self.assertRaises(IndexError, iter2.next)
+ try:
+ iter1.next()
+ except (IndexError, StopIteration):
+ pass
+ else:
+ self.fail("storage1 has more records")
+
+ try:
+ iter2.next()
+ except (IndexError, StopIteration):
+ pass
+ else:
+ self.fail("storage2 has more records")
+
iter1.close()
iter2.close()
Modified: relstorage/trunk/setup.py
===================================================================
--- relstorage/trunk/setup.py 2010-06-19 19:27:28 UTC (rev 113701)
+++ relstorage/trunk/setup.py 2010-06-19 22:01:34 UTC (rev 113702)
@@ -13,7 +13,7 @@
##############################################################################
"""A backend for ZODB that stores pickles in a relational database."""
-VERSION = "1.4.0b3"
+VERSION = "1.4.0c1"
# The choices for the Trove Development Status line:
# Development Status :: 5 - Production/Stable
More information about the checkins
mailing list