diff -r 3263f36aa50a -r 6893628e22fe trac/db.py
--- a/trac/db.py	Mon Oct 10 11:16:20 2005 +0200
+++ b/trac/db.py	Tue Oct 11 17:55:47 2005 +0200
@@ -24,6 +24,7 @@
 except ImportError:
     import dummy_threading as threading
     threading._get_ident = lambda: 0
+import weakref
 
 from trac.core import TracError
 
@@ -183,7 +184,10 @@
                     del self._active[tid]
                     if cnx not in self._dormant:
                         cnx.rollback()
-                        self._dormant.append(cnx)
+                        if cnx.poolable:
+                            self._dormant.append(cnx)
+                        else:
+                            self._cursize -= 1
                         self._available.notify()
         finally:
             self._available.release()
@@ -203,13 +207,21 @@
 
     class PyFormatCursor(sqlite.Cursor):
         def execute(self, sql, args=None):
-            if args:
-                sql = sql % (('?',) * len(args))
-            sqlite.Cursor.execute(self, sql, args or [])
+            try:
+                if args:
+                    sql = sql % (('?',) * len(args))
+                sqlite.Cursor.execute(self, sql, args or [])
+            except sqlite.OperationalError, e:
+                self.cnx.rollback()
+                raise e
         def executemany(self, sql, args=None):
-            if args:
-                sql = sql % (('?',) * len(args[0]))
-            sqlite.Cursor.executemany(self, sql, args or [])
+            try:
+                if args:
+                    sql = sql % (('?',) * len(args[0]))
+                sqlite.Cursor.executemany(self, sql, args or [])
+            except sqlite.OperationalError, e:
+                    self.cnx.rollback()
+                    raise e
         def _convert_row(self, row):
             return tuple([(isinstance(v, unicode) and [v.encode('utf-8')] or [v])[0]
                           for v in row])
@@ -224,6 +236,7 @@
             rows = sqlite.Cursor.fetchall(self)
             return rows != None and [self._convert_row(row)
                                      for row in rows] or None
+
                 
 except ImportError:
     try:
@@ -236,7 +249,11 @@
 class SQLiteConnection(ConnectionWrapper):
     """Connection wrapper for SQLite."""
 
-    __slots__ = ['cnx']
+    __slots__ = ['cnx', 'active_cursors']
+
+    poolable = False
+
+    poolable = False
 
     def __init__(self, path, params={}):
         assert have_pysqlite > 0
@@ -254,25 +271,39 @@
                                  'directory it is located in.' \
                                  % (getuser(), path)
 
-        timeout = int(params.get('timeout', 10000))
         if have_pysqlite == 2:
+            self.active_cursors = weakref.WeakKeyDictionary()
+            timeout = int(params.get('timeout', 10.0))
             # Convert unicode to UTF-8 bytestrings. This is case-sensitive, so
             # we need two converters
             sqlite.register_converter('text', str)
             sqlite.register_converter('TEXT', str)
 
             cnx = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES,
-                                 check_same_thread=False, timeout=timeout)
+                                 timeout=timeout)
         else:
+            timeout = int(params.get('timeout', 10000))
             cnx = sqlite.connect(path, timeout=timeout)
         ConnectionWrapper.__init__(self, cnx)
 
     if have_pysqlite == 2:
         def cursor(self):
-            return self.cnx.cursor(PyFormatCursor)
+            cursor = self.cnx.cursor(PyFormatCursor)
+            self.active_cursors[cursor] = True
+            cursor.cnx = self
+            return cursor
     else:
         def cursor(self):
             return self.cnx.cursor()
+
+    def _finalize_cursors(self):
+        cursors = self.active_cursors.keys()
+        for c in cursors:
+            c.close()
+
+    def rollback(self):
+        self._finalize_cursors()
+        self.cnx.rollback()
 
     def cast(self, column, type):
         return column
@@ -331,6 +362,8 @@
     """Connection wrapper for PostgreSQL."""
 
     __slots__ = ['cnx']
+
+    poolable = True
 
     def __init__(self, path, user=None, password=None, host=None, port=None,
                  params={}):

