Code

Ticket #3460: 3460-r8961-autocommit.diff

File 3460-r8961-autocommit.diff, 5.6 KB (added by Richard Davies <richard.davies@…>, 6 years ago)

Updated for Django 1.0, some problems remain (see my notes on ticket)

Line 
1Index: django/db/backends/postgresql/base.py
2===================================================================
3--- django/db/backends/postgresql/base.py       (revision 8961)
4+++ django/db/backends/postgresql/base.py       (working copy)
5@@ -96,9 +96,9 @@
6         self.validation = BaseDatabaseValidation()
7 
8     def _cursor(self, settings):
9-        set_tz = False
10+        first_cursor = False
11         if self.connection is None:
12-            set_tz = True
13+            first_cursor = True
14             if settings.DATABASE_NAME == '':
15                 from django.core.exceptions import ImproperlyConfigured
16                 raise ImproperlyConfigured("You need to specify DATABASE_NAME in your Django settings file.")
17@@ -112,10 +112,12 @@
18             if settings.DATABASE_PORT:
19                 conn_string += " port=%s" % settings.DATABASE_PORT
20             self.connection = Database.connect(conn_string, **self.options)
21-            self.connection.set_isolation_level(1) # make transactions transparent to all cursors
22+            self.connection.set_isolation_level(0)
23         cursor = self.connection.cursor()
24-        if set_tz:
25+        if first_cursor:
26             cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
27+            cursor.execute("SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED")
28+            self._commit()
29             if not hasattr(self, '_version'):
30                 self.__class__._version = get_version(cursor)
31             if self._version < (8, 0):
32Index: django/db/backends/postgresql_psycopg2/base.py
33===================================================================
34--- django/db/backends/postgresql_psycopg2/base.py      (revision 8961)
35+++ django/db/backends/postgresql_psycopg2/base.py      (working copy)
36@@ -66,9 +66,9 @@
37         self.validation = BaseDatabaseValidation()
38 
39     def _cursor(self, settings):
40-        set_tz = False
41+        first_cursor = False
42         if self.connection is None:
43-            set_tz = True
44+            first_cursor = True
45             if settings.DATABASE_NAME == '':
46                 from django.core.exceptions import ImproperlyConfigured
47                 raise ImproperlyConfigured("You need to specify DATABASE_NAME in your Django settings file.")
48@@ -82,12 +82,14 @@
49             if settings.DATABASE_PORT:
50                 conn_string += " port=%s" % settings.DATABASE_PORT
51             self.connection = Database.connect(conn_string, **self.options)
52-            self.connection.set_isolation_level(1) # make transactions transparent to all cursors
53+            self.connection.set_isolation_level(0)
54             self.connection.set_client_encoding('UTF8')
55         cursor = self.connection.cursor()
56         cursor.tzinfo_factory = None
57-        if set_tz:
58+        if first_cursor:
59             cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
60+            cursor.execute("SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED")
61+            self._commit()
62             if not hasattr(self, '_version'):
63                 self.__class__._version = get_version(cursor)
64             if self._version < (8, 0):
65Index: django/db/transaction.py
66===================================================================
67--- django/db/transaction.py    (revision 8961)
68+++ django/db/transaction.py    (working copy)
69@@ -185,7 +185,8 @@
70         savepoint_state[thread_ident] = [None]
71     tid = str(thread_ident).replace('-', '')
72     sid = "s%s_x%d" % (tid, len(savepoint_state[thread_ident]))
73-    connection._savepoint(sid)
74+    if is_managed():
75+        connection._savepoint(sid)
76     return sid
77 
78 def savepoint_rollback(sid):
79@@ -194,7 +195,8 @@
80     savepoints are not supported.
81     """
82     if thread.get_ident() in savepoint_state:
83-        connection._savepoint_rollback(sid)
84+        if is_managed():
85+            connection._savepoint_rollback(sid)
86 
87 def savepoint_commit(sid):
88     """
89@@ -202,7 +204,8 @@
90     savepoints are not supported.
91     """
92     if thread.get_ident() in savepoint_state:
93-        connection._savepoint_commit(sid)
94+        if is_managed():
95+            connection._savepoint_commit(sid)
96 
97 ##############
98 # DECORATORS #
99Index: django/core/management/commands/loaddata.py
100===================================================================
101--- django/core/management/commands/loaddata.py (revision 8961)
102+++ django/core/management/commands/loaddata.py (working copy)
103@@ -9,6 +9,13 @@
104 except NameError:
105     from sets import Set as set   # Python 2.3 fallback
106 
107+def _set_transaction_mode(connection):
108+    "Make sure a connection is not in autocommit mode."
109+    if hasattr(connection.connection, "autocommit"):
110+        connection.connection.autocommit(False)
111+    elif hasattr(connection.connection, "set_isolation_level"):
112+        connection.connection.set_isolation_level(1)
113+
114 class Command(BaseCommand):
115     option_list = BaseCommand.option_list + (
116         make_option('--verbosity', action='store', dest='verbosity', default='1',
117@@ -49,6 +56,7 @@
118         # the side effect of initializing the test database (if
119         # it isn't already initialized).
120         cursor = connection.cursor()
121+        _set_transaction_mode(connection)
122 
123         # Start transaction management. All fixtures are installed in a
124         # single transaction to ensure that all references are resolved.
125@@ -177,5 +185,6 @@
126         # edge case in MySQL: if the same connection is used to
127         # create tables, load data, and query, the query can return
128         # incorrect results. See Django #7572, MySQL #37735.
129+        # Also used to ensure _set_transaction_mode does not leak out
130         if commit:
131             connection.close()