Index: trac/db/pool.py
===================================================================
--- trac/db/pool.py	(revision 8268)
+++ trac/db/pool.py	(working copy)
@@ -41,16 +41,24 @@
         self._pool = pool
         self._key = key
         self._tid = tid
+        self._reusable = True
 
     def close(self):
         if self.cnx:
-            self._pool._return_cnx(self.cnx, self._key, self._tid)
+            self._pool._return_cnx(self.cnx, self._key, self._tid, self._reusable)
             self.cnx = None
             self.log = None
 
     def __del__(self):
         self.close()
 
+    def cursor(self):
+        try:
+            return ConnectionWrapper.cursor(self)
+        except Exception:
+            self._reusable = False
+            self.close()
+            raise
 
 def try_rollback(cnx):
     """Resets the Connection in a safe way, returning True when it succeeds.
@@ -89,7 +97,7 @@
             while True:
                 # First choice: Return the same cnx already used by the thread
                 if (tid, key) in self._active:
-                    cnx, num = self._active[(tid, key)]
+                    cnx, num, reuse = self._active[(tid, key)]
                     num += 1
                 # Second best option: Reuse a live pooled connection
                 elif key in self._pool_key:
@@ -115,7 +123,7 @@
                     self._pool_time.pop(0)
                     cnx = connector.get_connection(**kwargs)
                 if cnx:
-                    self._active[(tid, key)] = (cnx, num)
+                    self._active[(tid, key)] = (cnx, num, True)
                     return PooledConnection(self, cnx, key, tid, log)
                 # Worst option: wait until a connection pool slot is available
                 if timeout and (time.time() - start) > timeout:
@@ -129,20 +137,21 @@
         finally:
             self._available.release()
 
-    def _return_cnx(self, cnx, key, tid):
+    def _return_cnx(self, cnx, key, tid, reusable):
         self._available.acquire()
         try:
             assert (tid, key) in self._active
-            cnx, num = self._active[(tid, key)]
+            cnx, num, reuse = self._active[(tid, key)]
+            reuse = reuse and reusable
             if num == 1:
                 del self._active[(tid, key)]
                 self._available.notify() 
-                if cnx.poolable and try_rollback(cnx):
+                if cnx.poolable and try_rollback(cnx) and reuse:
                     self._pool.append(cnx)
                     self._pool_key.append(key)
                     self._pool_time.append(time.time())
             else:
-                self._active[(tid, key)] = (cnx, num - 1)
+                self._active[(tid, key)] = (cnx, num - 1, reuse)
         finally:
             self._available.release()
 

