summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2006-05-28 23:57:14 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2006-05-28 23:57:14 +0000
commit4b8897902105379a97363a0f3d58f1e87e65b42b (patch)
tree59ab875f00ea49f2768310347b1c197b2d723849
parent123cb1064ce6ecd841d32df08f7969acbc154cd9 (diff)
downloadsqlalchemy-4b8897902105379a97363a0f3d58f1e87e65b42b.tar.gz
pool needed weakref
modified auto rollback to only occur when no transaction more unit tests
-rw-r--r--lib/sqlalchemy/engine/base.py8
-rw-r--r--lib/sqlalchemy/engine/threadlocal.py2
-rw-r--r--lib/sqlalchemy/pool.py2
-rw-r--r--test/transaction.py35
4 files changed, 40 insertions, 7 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py
index f3573711b..eaaae29d2 100644
--- a/lib/sqlalchemy/engine/base.py
+++ b/lib/sqlalchemy/engine/base.py
@@ -167,7 +167,7 @@ class Connectable(object):
def _not_impl(self):
raise NotImplementedError()
engine = property(_not_impl, doc="returns the Engine which this Connectable is associated with.")
-
+
class Connection(Connectable):
"""represents a single DBAPI connection returned from the underlying connection pool. Provides
execution support for string-based SQL statements as well as ClauseElement, Compiled and DefaultGenerator objects.
@@ -214,6 +214,9 @@ class Connection(Connectable):
# extra step
if not self.in_transaction() and re.match(r'UPDATE|INSERT|CREATE|DELETE|DROP', statement.lstrip().upper()):
self._commit_impl()
+ def _autorollback(self):
+ if not self.in_transaction():
+ self._rollback_impl()
def close(self):
if self.__connection is not None:
self.__connection.close()
@@ -315,7 +318,8 @@ class Connection(Connectable):
try:
self.__engine.dialect.do_execute(c, statement, parameters, context=context)
except Exception, e:
- self._rollback_impl()
+ self._autorollback()
+ #self._rollback_impl()
if self.__close_with_result:
self.close()
raise exceptions.SQLError(statement, parameters, e)
diff --git a/lib/sqlalchemy/engine/threadlocal.py b/lib/sqlalchemy/engine/threadlocal.py
index 000a854b2..a96af4ea8 100644
--- a/lib/sqlalchemy/engine/threadlocal.py
+++ b/lib/sqlalchemy/engine/threadlocal.py
@@ -67,10 +67,8 @@ class TLConnection(base.Connection):
class TLTransaction(base.Transaction):
def commit(self):
- print "TL COMMIT"
base.Transaction.commit(self)
if not self.is_active:
- print "RESET"
self.connection.session.reset()
def rollback(self):
base.Transaction.rollback(self)
diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py
index ec6d24951..d13beefd6 100644
--- a/lib/sqlalchemy/pool.py
+++ b/lib/sqlalchemy/pool.py
@@ -71,7 +71,7 @@ def clear_managers():
class Pool(object):
def __init__(self, echo = False, use_threadlocal = True, logger=None, **kwargs):
- self._threadconns = {} #weakref.WeakValueDictionary()
+ self._threadconns = weakref.WeakValueDictionary()
self._use_threadlocal = use_threadlocal
self.echo = echo
self._logger = logger or util.Logger(origin='pool')
diff --git a/test/transaction.py b/test/transaction.py
index 32627b118..d4f6dc8c4 100644
--- a/test/transaction.py
+++ b/test/transaction.py
@@ -144,25 +144,56 @@ class TLTransactionTest(testbase.PersistTest):
finally:
external_connection.close()
- def testexplicitnesting(self):
- """tests nesting of tranacstions"""
+ def testmixednesting(self):
+ """tests nesting of transactions off the TLEngine directly inside of
+ tranasctions off the connection from the TLEngine"""
external_connection = tlengine.connect()
self.assert_(external_connection.connection is not tlengine.contextual_connect().connection)
conn = tlengine.contextual_connect()
trans = conn.begin()
+ trans2 = conn.begin()
tlengine.execute(users.insert(), user_id=1, user_name='user1')
tlengine.execute(users.insert(), user_id=2, user_name='user2')
tlengine.execute(users.insert(), user_id=3, user_name='user3')
tlengine.begin()
tlengine.execute(users.insert(), user_id=4, user_name='user4')
+ tlengine.begin()
tlengine.execute(users.insert(), user_id=5, user_name='user5')
+ tlengine.execute(users.insert(), user_id=6, user_name='user6')
+ tlengine.execute(users.insert(), user_id=7, user_name='user7')
+ tlengine.commit()
+ tlengine.execute(users.insert(), user_id=8, user_name='user8')
tlengine.commit()
+ trans2.commit()
trans.rollback()
conn.close()
try:
self.assert_(external_connection.scalar("select count(1) from query_users") == 0)
finally:
external_connection.close()
+
+ def testmoremixednesting(self):
+ """tests nesting of transactions off the connection from the TLEngine
+ inside of tranasctions off thbe TLEngine directly."""
+ external_connection = tlengine.connect()
+ self.assert_(external_connection.connection is not tlengine.contextual_connect().connection)
+ tlengine.begin()
+ connection = tlengine.contextual_connect()
+ connection.execute(users.insert(), user_id=1, user_name='user1')
+ tlengine.begin()
+ connection.execute(users.insert(), user_id=2, user_name='user2')
+ connection.execute(users.insert(), user_id=3, user_name='user3')
+ trans = connection.begin()
+ connection.execute(users.insert(), user_id=4, user_name='user4')
+ connection.execute(users.insert(), user_id=5, user_name='user5')
+ trans.commit()
+ tlengine.commit()
+ tlengine.rollback()
+ connection.close()
+ try:
+ self.assert_(external_connection.scalar("select count(1) from query_users") == 0)
+ finally:
+ external_connection.close()
def testconnections(self):
"""tests that contextual_connect is threadlocal"""