~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/services/database/transaction_policy.py

  • Committer: Raphael Badin
  • Date: 2012-01-06 08:27:55 UTC
  • mfrom: (14513.5.4 builder-history-lfa)
  • mto: This revision was merged to the branch mainline in revision 14654.
  • Revision ID: raphael.badin@canonical.com-20120106082755-95a0eh6nakv5hj3b
Merge devel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
    'DatabaseTransactionPolicy',
9
9
    ]
10
10
 
 
11
from functools import wraps
 
12
 
11
13
from psycopg2.extensions import TRANSACTION_STATUS_IDLE
12
14
import transaction
13
15
from zope.component import getUtility
92
94
 
93
95
        :raise TransactionInProgress: if a transaction was already ongoing.
94
96
        """
95
 
        self._checkNoTransaction(
96
 
            "Entered DatabaseTransactionPolicy while in a transaction.")
 
97
        # We must check the transaction status before checking the current
 
98
        # policy because getting the policy causes a status change.
 
99
        in_transaction = self._isInTransaction()
97
100
        self.previous_policy = self._getCurrentPolicy()
 
101
        # If the current transaction is read-write and we're moving to
 
102
        # read-only then we should check for a transaction. If the current
 
103
        # policy is read-only then we don't care if a transaction is in
 
104
        # progress.
 
105
        if in_transaction and self.read_only and not self.previous_policy:
 
106
            raise TransactionInProgress(
 
107
                "Attempting to enter a read-only transaction while holding "
 
108
                "open a read-write transaction.")
98
109
        self._setPolicy(self.read_only)
99
110
        # Commit should include the policy itself.  If this breaks
100
111
        # because the transaction was already in a failed state before
133
144
    def _isInTransaction(self):
134
145
        """Is our store currently in a transaction?"""
135
146
        pg_connection = self.store._connection._raw_connection
136
 
        status = pg_connection.get_transaction_status()
137
 
        return status != TRANSACTION_STATUS_IDLE
 
147
        if pg_connection is None:
 
148
            return False
 
149
        else:
 
150
            status = pg_connection.get_transaction_status()
 
151
            return status != TRANSACTION_STATUS_IDLE
138
152
 
139
153
    def _checkNoTransaction(self, error_msg):
140
154
        """Verify that no transaction is ongoing.
183
197
        """
184
198
        self.store.execute(
185
199
            "SET %s TO %s" % (self.db_switch, quote(read_only)))
 
200
 
 
201
    @classmethod
 
202
    def readOnly(cls, func):
 
203
        @wraps(func)
 
204
        def wrapper(*args, **kwargs):
 
205
            with cls(read_only=True):
 
206
                return func(*args, **kwargs)
 
207
        return wrapper
 
208
 
 
209
    @classmethod
 
210
    def readWrite(cls, func):
 
211
        @wraps(func)
 
212
        def wrapper(*args, **kwargs):
 
213
            with cls(read_only=False):
 
214
                return func(*args, **kwargs)
 
215
        return wrapper