Commit e0b4a5bb authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

ZMySQLDA: automatically switch isolation if the first query contains SELECT.

parent 08b24082
......@@ -107,7 +107,9 @@
!<em>isolation_level</em> at the begining of the connection string
will set the transaction isolation level in each transaction. The
value should be one of REPEATABLE-READ, READ-COMMITTED,
READ-UNCOMMITTED or SERIALIZABLE.
READ-UNCOMMITTED or SERIALIZABLE. If not specified, REPEATABLE-READ
is used for if the first query in a Zope transaction is SELECT query,
otherwise READ-COMMITTED is used.
</dd>
<dd>
Transactions are highly recommended. Using a named lock in
......
......@@ -303,7 +303,7 @@ class DB(TM):
FIELD_TYPE.TINY: "i", FIELD_TYPE.YEAR: "i",
}
_p_oid=_p_changed=_registered=None
_p_oid=_p_changed=_registered=_current_isolation_level=None
def __del__(self):
if self.db is not None:
......@@ -440,7 +440,6 @@ class DB(TM):
def query(self, query_string, max_rows=1000):
"""Execute 'query_string' and return at most 'max_rows'."""
self._use_TM and self._register()
desc = None
if isinstance(query_string, six.text_type):
query_string = query_string.encode('utf-8')
......@@ -449,6 +448,17 @@ class DB(TM):
# Unfortunately, MySQLdb does not want to be graceful.
if query_string[-1:] == b';':
query_string = query_string[:-1]
if self._use_TM and not self._registered:
if self._isolation_level:
self._current_isolation_level = self._isolation_level
else:
for qs in query_string.split(b'\0'):
if match_select(qs.strip()):
self._current_isolation_level = 'REPEATABLE-READ'
break
else:
self._current_isolation_level = 'READ-COMMITTED'
self._register()
for qs in query_string.split(b'\0'):
qs = qs.strip()
if qs:
......@@ -493,8 +503,8 @@ class DB(TM):
try:
self._transaction_begun = True
if self._transactions:
if self._isolation_level:
self._query("SET TRANSACTION ISOLATION LEVEL %s" % self._isolation_level.replace('-', ' '))
if self._current_isolation_level:
self._query("SET TRANSACTION ISOLATION LEVEL %s" % self._current_isolation_level.replace('-', ' '))
self._query("BEGIN", allow_reconnect=True)
if self._mysql_lock:
self._query("SELECT GET_LOCK('%s',0)" % self._mysql_lock, allow_reconnect=not self._transactions)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment