[Sqlalchemy-commits] [1435] sqlalchemy/branches/schema/test: added auto-rollback in pool return conn
Brought to you by:
zzzeek
From: <co...@sq...> - 2006-05-11 15:56:32
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><style type="text/css"><!-- #msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; } #msg dt { float: left; width: 6em; font-weight: bold; } #msg dt:after { content:':';} #msg dl, #msg dt, #msg ul, #msg li { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; } #msg dl a { font-weight: bold} #msg dl a:link { color:#fc3; } #msg dl a:active { color:#ff0; } #msg dl a:visited { color:#cc6; } h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; } #msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; } #msg ul, pre { overflow: auto; } #patch { width: 100%; } #patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;} #patch .propset h4, #patch .binary h4 {margin:0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;} #patch .propset .diff, #patch .binary .diff {padding:10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;} #patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;} #patch .lines, .info {color:#888;background:#fff;} --></style> <title>[1435] sqlalchemy/branches/schema/test: added auto-rollback in pool return connection, so that locks can be cleared when connection is returned</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1435</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-05-11 10:56:19 -0500 (Thu, 11 May 2006)</dd> </dl> <h3>Log Message</h3> <pre>added auto-rollback in pool return connection, so that locks can be cleared when connection is returned added transaction unittest module</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemybranchesschemalibsqlalchemypoolpy">sqlalchemy/branches/schema/lib/sqlalchemy/pool.py</a></li> <li><a href="#sqlalchemybranchesschematestalltestspy">sqlalchemy/branches/schema/test/alltests.py</a></li> </ul> <h3>Added Paths</h3> <ul> <li><a href="#sqlalchemybranchesschematesttransactionpy">sqlalchemy/branches/schema/test/transaction.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemybranchesschemalibsqlalchemypoolpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/lib/sqlalchemy/pool.py (1434 => 1435)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/lib/sqlalchemy/pool.py 2006-05-10 23:46:20 UTC (rev 1434) +++ sqlalchemy/branches/schema/lib/sqlalchemy/pool.py 2006-05-11 15:56:19 UTC (rev 1435) </span><span class="lines">@@ -137,6 +137,7 @@ </span><span class="cx"> def invalidate(self): </span><span class="cx"> if self.pool.echo: </span><span class="cx"> self.pool.log("Invalidate connection %s" % repr(self.connection)) </span><ins>+ self.connection.rollback() </ins><span class="cx"> self.connection = None </span><span class="cx"> self.pool.return_invalid() </span><span class="cx"> def cursor(self): </span><span class="lines">@@ -158,6 +159,7 @@ </span><span class="cx"> if self.connection is not None: </span><span class="cx"> if self.pool.echo: </span><span class="cx"> self.pool.log("Connection %s being returned to pool" % repr(self.connection)) </span><ins>+ self.connection.rollback() </ins><span class="cx"> self.pool.return_conn(self) </span><span class="cx"> self.pool = None </span><span class="cx"> self.connection = None </span></span></pre></div> <a id="sqlalchemybranchesschematestalltestspy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/test/alltests.py (1434 => 1435)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/test/alltests.py 2006-05-10 23:46:20 UTC (rev 1434) +++ sqlalchemy/branches/schema/test/alltests.py 2006-05-11 15:56:19 UTC (rev 1435) </span><span class="lines">@@ -15,6 +15,7 @@ </span><span class="cx"> # connectivity, execution </span><span class="cx"> 'pool', </span><span class="cx"> 'engine', </span><ins>+ 'transaction', </ins><span class="cx"> </span><span class="cx"> # schema/tables </span><span class="cx"> 'reflection', </span></span></pre></div> <a id="sqlalchemybranchesschematesttransactionpy"></a> <div class="addfile"><h4>Added: sqlalchemy/branches/schema/test/transaction.py (1434 => 1435)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/test/transaction.py 2006-05-10 23:46:20 UTC (rev 1434) +++ sqlalchemy/branches/schema/test/transaction.py 2006-05-11 15:56:19 UTC (rev 1435) </span><span class="lines">@@ -0,0 +1,63 @@ </span><ins>+ +import testbase +import unittest, sys, datetime +import tables +db = testbase.db +from sqlalchemy import * + +class TransactionTest(testbase.PersistTest): + def setUpAll(self): + global users, metadata + metadata = MetaData() + users = Table('query_users', metadata, + Column('user_id', INT, primary_key = True), + Column('user_name', VARCHAR(20)), + ) + users.create(testbase.db) + + def tearDown(self): + testbase.db.connect().execute(users.delete()) + def tearDownAll(self): + users.drop(testbase.db) + + @testbase.unsupported('mysql') + def testrollback(self): + """test a basic rollback""" + connection = testbase.db.connect() + transaction = connection.begin() + connection.execute(users.insert(), user_id=1, user_name='user1') + connection.execute(users.insert(), user_id=2, user_name='user2') + connection.execute(users.insert(), user_id=3, user_name='user3') + transaction.rollback() + + result = connection.execute("select * from query_users") + assert len(result.fetchall()) == 0 + connection.close() + +class AutoRollbackTest(testbase.PersistTest): + def setUpAll(self): + global metadata + metadata = MetaData() + + def tearDownAll(self): + metadata.drop_all(testbase.db) + + def testrollback_deadlock(self): + """test that returning connections to the pool clears any object locks.""" + conn1 = testbase.db.connect() + conn2 = testbase.db.connect() + users = Table('deadlock_users', metadata, + Column('user_id', INT, primary_key = True), + Column('user_name', VARCHAR(20)), + ) + users.create(conn1) + conn1.execute("select * from deadlock_users") + conn1.close() + # without auto-rollback in the connection pool's return() logic, this deadlocks in Postgres, + # because conn1 is returned to the pool but still has a lock on "deadlock_users" + # comment out the rollback in pool/ConnectionFairy._close() to see ! + users.drop(conn2) + conn2.close() + +if __name__ == "__main__": + testbase.main() </ins></span></pre> </div> </div> </body> </html> |