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 @@ ...@@ -107,7 +107,9 @@
!<em>isolation_level</em> at the begining of the connection string !<em>isolation_level</em> at the begining of the connection string
will set the transaction isolation level in each transaction. The will set the transaction isolation level in each transaction. The
value should be one of REPEATABLE-READ, READ-COMMITTED, 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>
<dd> <dd>
Transactions are highly recommended. Using a named lock in Transactions are highly recommended. Using a named lock in
......
...@@ -303,7 +303,7 @@ class DB(TM): ...@@ -303,7 +303,7 @@ class DB(TM):
FIELD_TYPE.TINY: "i", FIELD_TYPE.YEAR: "i", 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): def __del__(self):
if self.db is not None: if self.db is not None:
...@@ -440,7 +440,6 @@ class DB(TM): ...@@ -440,7 +440,6 @@ class DB(TM):
def query(self, query_string, max_rows=1000): def query(self, query_string, max_rows=1000):
"""Execute 'query_string' and return at most 'max_rows'.""" """Execute 'query_string' and return at most 'max_rows'."""
self._use_TM and self._register()
desc = None desc = None
if isinstance(query_string, six.text_type): if isinstance(query_string, six.text_type):
query_string = query_string.encode('utf-8') query_string = query_string.encode('utf-8')
...@@ -449,6 +448,17 @@ class DB(TM): ...@@ -449,6 +448,17 @@ class DB(TM):
# Unfortunately, MySQLdb does not want to be graceful. # Unfortunately, MySQLdb does not want to be graceful.
if query_string[-1:] == b';': if query_string[-1:] == b';':
query_string = query_string[:-1] 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'): for qs in query_string.split(b'\0'):
qs = qs.strip() qs = qs.strip()
if qs: if qs:
...@@ -493,8 +503,8 @@ class DB(TM): ...@@ -493,8 +503,8 @@ class DB(TM):
try: try:
self._transaction_begun = True self._transaction_begun = True
if self._transactions: if self._transactions:
if self._isolation_level: if self._current_isolation_level:
self._query("SET TRANSACTION ISOLATION LEVEL %s" % self._isolation_level.replace('-', ' ')) self._query("SET TRANSACTION ISOLATION LEVEL %s" % self._current_isolation_level.replace('-', ' '))
self._query("BEGIN", allow_reconnect=True) self._query("BEGIN", allow_reconnect=True)
if self._mysql_lock: if self._mysql_lock:
self._query("SELECT GET_LOCK('%s',0)" % self._mysql_lock, allow_reconnect=not self._transactions) 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