Changeset 3314

Show
Ignore:
Timestamp:
08/19/07 12:07:48 (1 year ago)
Author:
ed
Message:

Major re-write to the way that transactions are handled in the bizobj and database layers.

These changes are designed to work within the entire framework; i.e., applications, forms, bizobjs and cursors. If you use any single piece of the framework separately, such as a raw cursor, you will have to manage transactions yourself.

Transactions now happen happen by default when calling biz.save()/saveAll() and biz.delete()/deleteAll(). If for some reason you do not want transactions, you must call them with the parameter startTransaction=False.

Only one bizobj will begin and commit/rollback. All others do not touch transactions, as they are within the current transaction. Upon a save or delete method being called, the bizobj will request the transaction 'token' from the app. If no other bizobj has started a transaction, it will have True returned from the request, and the bizobj will handle the transaction. If there are related bizobjs who in turn have their save/delete methods called, their requests for the token will be denied, so they will not do anything regarding transactions. When the process is completed in the initial method that requested the token, either a commit or rollback will be called, and the token released.

This design eliminates the problem with nested and chained bizobjs starting and/or ending multiple transactions. Only the original bizobj in the process can manage transactions, and only from the method that was originally called.

The 'AutoCommit?' property has been removed. Defaulting transactions to being used by default will handle the call to commit(). Again, if you deal with cursors directly (as is done in dPref.py), the commit calls must also be handled manually.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/dabo/biz/dAutoBizobj.py

    r3303 r3314  
    4444    g._toExc = {} 
    4545    for biz in g._AutoTables.values(): 
    46         ac = biz.AutoCommit 
    47         biz.AutoCommit = True 
    48         biz.CreateTable() 
    49  
    50         biz.AutoCommit = ac 
     46        biz.createTable() 
    5147 
    5248    if g._toExc: 
     
    139135                    except dException.DBNoAccessException: 
    140136                        dabo.ui.stop(_("Could not access the database with the given username and password.")) 
    141                         _WriteQueriesToFile(g._toExc) 
     137                        _writeQueriesToFile(g._toExc) 
    142138                        raise dException.DBNoAccessException 
    143139                    else: 
     
    150146                            except dException.DBNoAccessExeption: 
    151147                                dabo.ui.stop(_("Could not setup the database. Access was denied.")) 
    152                                 _WriteQueriesToFile(g._toExc) 
     148                                _writeQueriesToFile(g._toExc) 
    153149                                raise dException.DBNoAccessException 
    154150 
    155151                else: 
    156152                    login.release() 
    157                     _WriteQueriesToFile(g._toExc) 
     153                    _writeQueriesToFile(g._toExc) 
    158154                    raise dException.DBNoAccessException 
    159155 
    160156        else: 
    161             _WriteQueriesToFile(g._toExc) 
     157            _writeQueriesToFile(g._toExc) 
    162158            raise dException.DBNoAccessException 
    163159 
    164160 
    165 def _WriteQueriesToFile(queries): 
     161def _writeQueriesToFile(queries): 
    166162    f = open("queries.sql", "w") 
    167163    for k in queries.keys(): 
     
    171167 
    172168    f.close() 
     169 
     170 
    173171 
    174172class dAutoBizobj(dBizobj): 
     
    245243 
    246244 
    247     def CreateTable(self): 
     245    def createTable(self): 
    248246        """Create the tables that has been asigned to this bizobj.""" 
    249247        if self._table is None: 
  • trunk/dabo/biz/dBizobj.py

    r3303 r3314  
    6161 
    6262        # Various attributes used for Properties 
    63         self._autoCommit = False 
    6463        self._caption = "" 
    6564        self._dataSource = "" 
     
    167166        crs.BackendObject = cf.getBackendObject() 
    168167        crs.sqlManager = self.SqlManager 
    169         crs.AutoCommit = self.AutoCommit 
    170168        crs._bizobj = self 
    171169        if self.RequeryOnLoad: 
     
    263261 
    264262 
    265     def saveAll(self, startTransaction=False, topLevel=True): 
     263    def saveAll(self, startTransaction=True): 
    266264        """Saves all changes to the bizobj and children.""" 
    267         useTransact = startTransaction or topLevel 
    268265        cursor = self._CurrentCursor 
    269266        current_row = self.RowNumber 
    270  
    271         if useTransact: 
    272             # Tell the cursor to begin a transaction, if needed. 
    273             cursor.beginTransaction() 
     267        app = self.Application 
     268        isTransactionManager = False 
     269        if startTransaction: 
     270            isTransactionManager = app.getTransactionToken(self) 
     271            if isTransactionManager: 
     272                cursor.beginTransaction() 
    274273 
    275274        try: 
    276275            self.scanChangedRows(self.save, includeNewUnchanged=self.SaveNewUnchanged, 
    277                     startTransaction=False, topLevel=False) 
     276                    startTransaction=False) 
     277            if isTransactionManager: 
     278                cursor.commitTransaction() 
     279                app.releaseTransactionToken(self) 
     280 
    278281        except dException.ConnectionLostException, e: 
    279282            self.RowNumber = current_row 
     
    281284        except dException.DBQueryException, e: 
    282285            # Something failed; reset things. 
    283             if useTransact
     286            if isTransactionManager
    284287                cursor.rollbackTransaction() 
     288                app.releaseTransactionToken(self) 
    285289            # Pass the exception to the UI 
    286290            self.RowNumber = current_row 
    287291            raise dException.DBQueryException, e 
    288292        except dException.dException, e: 
    289             if useTransact
     293            if isTransactionManager
    290294                cursor.rollbackTransaction() 
     295                app.releaseTransactionToken(self) 
    291296            self.RowNumber = current_row 
    292297            raise 
    293  
    294         if useTransact: 
    295             cursor.commitTransaction() 
    296298 
    297299        if current_row >= 0: 
     
    301303 
    302304 
    303     def save(self, startTransaction=False, topLevel=True): 
     305    def save(self, startTransaction=True): 
    304306        """Save any changes that have been made in the current row. 
    305307 
     
    319321        self._validate() 
    320322 
    321         useTransact = startTransaction or topLevel 
    322         if useTransact: 
    323             # Tell the cursor to begin a transaction, if needed. 
    324             cursor.beginTransaction() 
     323        app = self.Application 
     324        isTransactionManager = False 
     325        if startTransaction: 
     326            isTransactionManager = app.getTransactionToken(self) 
     327            if isTransactionManager: 
     328                cursor.beginTransaction() 
    325329 
    326330        # Save to the Database, but first save the IsAdding flag as the save() call 
     
    338342                # we need to save all rows that have changed. 
    339343                if child.RowCount > 0: 
    340                     child.saveAll(startTransaction=False, topLevel=False
     344                    child.saveAll(startTransaction=False
    341345 
    342346            # Finish the transaction, and requery the children if needed. 
    343             if useTransact
     347            if isTransactionManager
    344348                cursor.commitTransaction() 
     349                app.releaseTransactionToken(self) 
    345350            if self.RequeryChildOnSave: 
    346351                self.requeryAllChildren() 
     
    354359        except dException.DBQueryException, e: 
    355360            # Something failed; reset things. 
    356             if useTransact
     361            if isTransactionManager
    357362                cursor.rollbackTransaction() 
     363                app.releaseTransactionToken(self) 
    358364            # Pass the exception to the UI 
    359365            raise dException.DBQueryException, e 
     
    361367        except dException.dException, e: 
    362368            # Something failed; reset things. 
    363             if useTransact
     369            if isTransactionManager
    364370                cursor.rollbackTransaction() 
     371                app.releaseTransactionToken(self) 
    365372            # Pass the exception to the UI 
    366373            raise 
    367  
    368         # Some backends (Firebird particularly) need to be told to write 
    369         # their changes even if no explicit transaction was started. 
    370         cursor.flush() 
    371374 
    372375        # Two hook methods: one specific to Save(), and one which is called after any change 
     
    405408 
    406409 
    407     def deleteAllChildren(self, startTransaction=False): 
     410    def deleteAllChildren(self, startTransaction=True): 
    408411        """Delete all children associated with the current record without 
    409412        deleting the current record in this bizobj. 
    410413        """ 
    411414        cursor = self._CurrentCursor 
     415        app = self.Application 
    412416        errMsg = self.beforeDeleteAllChildren() 
    413417        if errMsg: 
    414418            raise dException.BusinessRuleViolation, errMsg 
    415419 
     420        isTransactionManager = False 
    416421        if startTransaction: 
    417             cursor.beginTransaction() 
     422            isTransactionManager = app.getTransactionToken(self) 
     423            if isTransactionManager: 
     424                cursor.beginTransaction() 
    418425 
    419426        try: 
    420427            for child in self.__children: 
    421428                child.deleteAll(startTransaction=False) 
    422             if startTransaction
     429            if isTransactionManager
    423430                cursor.commitTransaction() 
    424             self.afterDeleteAllChildren(
     431               app.releaseTransactionToken(self
    425432 
    426433        except dException.DBQueryException, e: 
    427             if startTransaction
     434            if isTransactionManager
    428435                cursor.rollbackTransaction() 
     436                app.releaseTransactionToken(self) 
    429437            raise dException.DBQueryException, e 
    430438        except StandardError, e: 
    431             if startTransaction
     439            if isTransactionManager
    432440                cursor.rollbackTransaction() 
     441                app.releaseTransactionToken(self) 
    433442            raise StandardError, e 
    434  
    435  
    436     def delete(self, startTransaction=False): 
     443        self.afterDeleteAllChildren() 
     444 
     445 
     446    def delete(self, startTransaction=True, inLoop=False): 
    437447        """Delete the current row of the data set.""" 
     448        app = self.Application 
    438449        cursor = self._CurrentCursor 
    439450        errMsg = self.beforeDelete() 
     
    452463                    raise dException.dException, _("Deletion prohibited - there are related child records.") 
    453464 
     465        isTransactionManager = False 
    454466        if startTransaction: 
    455             cursor.beginTransaction() 
     467            isTransactionManager = app.getTransactionToken(self) 
     468            if isTransactionManager: 
     469                cursor.beginTransaction() 
    456470 
    457471        try: 
     
    470484                    child.requery() 
    471485 
    472             if startTransaction
     486            if isTransactionManager
    473487                cursor.commitTransaction() 
    474  
    475             # Some backends (Firebird particularly) need to be told to write 
    476             # their changes even if no explicit transaction was started. 
    477             cursor.flush() 
     488                app.releaseTransactionToken(self) 
     489 
     490            if not inLoop: 
     491                self.afterPointerMove() 
     492                self.afterChange() 
     493                self.afterDelete() 
     494        except dException.DBQueryException, e: 
     495            if isTransactionManager: 
     496                cursor.rollbackTransaction() 
     497                app.releaseTransactionToken(self) 
     498            raise dException.DBQueryException, e 
     499        except StandardError, e: 
     500            if isTransactionManager: 
     501                cursor.rollbackTransaction() 
     502                app.releaseTransactionToken(self) 
     503            raise StandardError, e 
     504 
     505 
     506    def deleteAll(self, startTransaction=True): 
     507        """ Delete all rows in the data set.""" 
     508        isTransactionManager = False 
     509        if startTransaction: 
     510            isTransactionManager = app.getTransactionToken(self) 
     511            if isTransactionManager: 
     512                cursor.beginTransaction() 
     513        try: 
     514            while self.RowCount > 0: 
     515                self.first() 
     516                ret = self.delete(startTransaction=False, inLoop=True) 
     517            if isTransactionManager: 
     518                cursor.commitTransaction() 
     519                app.releaseTransactionToken(self) 
    478520 
    479521            self.afterPointerMove() 
     
    481523            self.afterDelete() 
    482524        except dException.DBQueryException, e: 
    483             if startTransaction
     525            if isTransactionManager
    484526                cursor.rollbackTransaction() 
     527                app.releaseTransactionToken(self) 
    485528            raise dException.DBQueryException, e 
    486529        except StandardError, e: 
    487             if startTransaction
     530            if isTransactionManager
    488531                cursor.rollbackTransaction() 
     532                app.releaseTransactionToken(self) 
    489533            raise StandardError, e 
    490  
    491  
    492     def deleteAll(self, startTransaction=False): 
    493         """ Delete all rows in the data set.""" 
    494         while self.RowCount > 0: 
    495             self.first() 
    496             ret = self.delete(startTransaction) 
    497534 
    498535 
     
    759796 
    760797        except dException.DBQueryException, e: 
    761             # Something failed; reset things. 
    762             cursor.rollbackTransaction() 
    763798            # Pass the exception to the UI 
    764799            raise dException.DBQueryException, e 
    765800 
    766801        except dException.NoRecordsException: 
    767             # No need to abort the transaction because of this, but 
    768             # we still need to pass the exception to the UI 
     802            # Pass the exception to the UI 
    769803            uiException = dException.NoRecordsException 
    770804 
    771805        except dException.dException, e: 
    772             # Something failed; reset things. 
    773             cursor.rollbackTransaction() 
    774806            # Pass the exception to the UI 
    775807            raise dException.dException, e 
     
    14681500        """ 
    14691501        for crs in self.__cursors.values(): 
    1470             crs.AutoCommit = self._autoCommit 
    14711502            crs.AutoPopulatePK = self._autoPopulatePK 
    14721503            crs.AutoQuoteNames = self._autoQuoteNames 
     
    14781509     
    14791510 
    1480     def _getAutoCommit(self): 
    1481         return self._CurrentCursor.AutoCommit 
    1482  
    1483     def _setAutoCommit(self, val): 
    1484         self._autoCommit = val 
    1485         self._syncWithCursors() 
    1486  
    1487  
     1511    ## Property getter/setter methods ## 
    14881512    def _getAutoPopulatePK(self): 
    14891513        try: 
     
    18421866 
    18431867    ### -------------- Property Definitions ------------------  ## 
    1844     AutoCommit = property(_getAutoCommit, _setAutoCommit, None, 
    1845             _("Do we need explicit begin/commit/rollback commands for transactions?  (bool)")) 
    1846  
    18471868    AutoPopulatePK = property(_getAutoPopulatePK, _setAutoPopulatePK, None, 
    18481869            _("Determines if we are using a table that auto-generates its PKs. (bool)")) 
  • trunk/dabo/biz/test/test_dBizobj.py

    r3271 r3314  
    4545 
    4646    ## - Begin property unit tests - 
    47     def test_AutoCommit(self): 
    48         biz = self.biz 
    49         self.assertEqual(biz.AutoCommit, False) 
    50         biz.AutoCommit = True 
    51         self.assertEqual(biz.AutoCommit, True) 
    52  
    5347    def test_AutoSQL(self): 
    5448        biz = self.biz 
  • trunk/dabo/dApp.py

    r3303 r3314  
    187187        # Create the framework-level preference manager 
    188188        self._frameworkPrefs = dabo.dPref(key="dabo_framework") 
     189        # Hold a reference to the bizobj, if any, controlling the current  
     190        # database transaction 
     191        self._transactionBizobj = None 
    189192 
    190193        # List of form classes to open on App Startup 
     
    398401                vers = -1 
    399402            localVers = self._currentUpdateVersion() 
    400             ret = localVers < vers 
     403            ret = (localVers != vers) 
    401404        prf.setValue("last_check", now) 
    402405        return ret 
     
    707710                self.dbConnectionDefs[k] = ci 
    708711                self.dbConnectionNameToFiles[k] = connFile 
     712 
     713 
     714    def getTransactionToken(self, biz): 
     715        """Only one bizobj at a time can begin and end transactions. This allows the bizobj 
     716        to query the app for the 'token', which is simply an acknowledgement that there 
     717        is no other transaction pending. If the bizobj gets the token, further requests for the 
     718        token will receive a reply of False, meaning that they should not be handling the transaction. 
     719        """ 
     720        print "TOKEN REQUEST", biz 
     721        if self._transactionBizobj is None: 
     722            print "TOKEN SET TO ", biz 
     723            self._transactionBizobj = biz 
     724            return True 
     725        else: 
     726            print "TOKEN DENIED; holder=", self._transactionBizobj 
     727            return False 
     728 
     729 
     730    def releaseTransactionToken(self, biz): 
     731        """When a process that would normally close a transaction happens, the bizobj that is 
     732        holding the transaction token calls this message to return the token. A check is run to  
     733        ensure that the releasing bizobj is the one currently holding the token; if it is, the  
     734        internal attribute is reset. 
     735        """ 
     736        print "APP RELEASE TOKEN FROM:", biz, 
     737        if biz is self._transactionBizobj: 
     738            self._transactionBizobj = None 
     739            print "RELEASED", 
     740        print "" 
    709741 
    710742 
  • trunk/dabo/dPref.py

    r3303 r3314  
    7373            if not  "daboprefs" in self._cursor.getTables(): 
    7474                self._cursor.execute("create table daboprefs (ckey text not null, ctype text not null, cvalue text not null)") 
     75                self._cursor.commitTransaction() 
    7576        else: 
    7677            self._cursor = crs 
    7778            self._cxn = cxn 
    78         if self._cursor: 
    79             self._cursor.AutoCommit = True 
    8079         
    8180         
     
    221220            prm = (key, typ, val) 
    222221            crs.execute(sql, prm) 
     222        self._cursor.commitTransaction() 
    223223     
    224224     
     
    235235            self._cursor.execute("delete from daboprefs where ckey like ? ", (key, )) 
    236236        self._deletionCache = {} 
     237        self._cursor.commitTransaction() 
    237238     
    238239     
     
    261262            if self._cache.has_key(att): 
    262263                del self._cache[att] 
    263              
     264        self._cursor.commitTransaction() 
     265 
    264266     
    265267    def deleteAllPrefs(self): 
     
    282284            self._cache = {} 
    283285            self._deletionCache[key] = None 
    284              
     286        self._cursor.commitTransaction() 
     287 
    285288     
    286289    def flushCache(self): 
     
    377380        prm = (key, newTyp, val) 
    378381        self._cursor.execute(sql, prm) 
     382        self._cursor.commitTransaction() 
    379383     
    380384     
  • trunk/dabo/db/dBackend.py

    r3303 r3314  
    2626    def __init__(self): 
    2727        self._baseClass = dBackend 
    28         self._autoCommit = False 
    29         # This forces the setting on the connection 
    30         self.AutoCommit = False 
    3128        super(dBackend, self).__init__() 
    3229        self.dbModuleName = None 
     
    197194 
    198195 
    199     def getAutoCommitStatus(self, cursor): 
    200         return self._autoCommit 
    201  
    202  
    203     def setAutoCommitStatus(self, cursor, val): 
    204         if hasattr(self._connection, "autocommit"): 
    205             self._connection.autocommit(val) 
    206             self._autoCommit = val 
    207         else: 
    208             # Without an autocommit method, assume no autocommit. 
    209             self._autoCommit = False 
    210             if val: 
    211                 raise ValueError, "Can't set AutoCommit to True for this backend." 
    212  
    213  
    214196    def beginTransaction(self, cursor): 
    215197        """ Begin a SQL transaction. Override in subclasses if needed.""" 
    216         pass 
     198        self._connection.begin() 
     199        dabo.dbActivityLog.write("SQL: begin") 
    217200 
    218201 
    219202    def commitTransaction(self, cursor): 
    220203        """ Commit a SQL transaction.""" 
    221         if not cursor.AutoCommit: 
    222             self._connection.commit() 
    223             dabo.dbActivityLog.write("SQL: commit") 
     204        self._connection.commit() 
     205        dabo.dbActivityLog.write("SQL: commit") 
    224206 
    225207 
  • trunk/dabo/db/dCursorMixin.py

    r3303 r3314  
    353353            return 
    354354        ac = self.AuxCursor 
    355         ac.AutoCommit = self.AutoCommit 
    356355        ac.AutoPopulatePK = self.AutoPopulatePK 
    357356        ac.AutoQuoteNames = self.AutoQuoteNames 
     
    10571056 
    10581057 
    1059     def save(self, allRows=False, useTransaction=False): 
     1058    def save(self, allRows=False): 
    10601059        """ Save any changes to the data back to the data store.""" 
    10611060        # Make sure that there is data to save 
     
    10691068                self.__saverow(row) 
    10701069            except dException.DBQueryException, e: 
    1071                 # Error was raised. Exit and rollback the changes if 
    1072                 # this object started the transaction. 
     1070                # Error was encountered. Raise an exception so that the 
     1071                # calling bizobj can rollback the transaction if necessary 
    10731072                dabo.dbActivityLog.write(_("DBQueryException encountered in save(): %s") % e) 
    1074                 if useTransaction: 
    1075                     self.rollbackTransaction() 
    10761073                raise dException.DBQueryException, e 
    10771074            except StandardError, e: 
     
    10801077                    raise dException.ConnectionLostException, e 
    10811078                else: 
    1082                     # Error was raised. Exit and rollback the changes if 
    1083                     # this object started the transaction. 
    1084                     if useTransaction: 
    1085                         self.rollbackTransaction() 
     1079                    # Error was encountered. Raise an exception so that the 
     1080                    # calling bizobj can rollback the transaction if necessary 
    10861081                    raise 
    10871082 
    10881083        self._syncAuxProperties() 
    1089         if useTransaction: 
    1090             self.beginTransaction() 
    10911084 
    10921085        # Faster to deal with 2 specific cases: all rows or just current row 
     
    11001093            if pk in self._mementos.keys(): 
    11011094                saverow(self.RowNumber) 
    1102  
    1103         if useTransaction: 
    1104             self.commitTransaction() 
    11051095 
    11061096 
     
    17271717        ret = None 
    17281718        if self.BackendObject: 
    1729             if not self.AutoCommit: 
    1730                 ret = self.BackendObject.beginTransaction(self.AuxCursor) 
     1719            ret = self.BackendObject.beginTransaction(self.AuxCursor) 
    17311720        return ret 
    17321721 
     
    17361725        ret = None 
    17371726        if self.BackendObject: 
    1738             if not self.AutoCommit: 
    1739                 ret = self.BackendObject.commitTransaction(self.AuxCursor) 
     1727            ret = self.BackendObject.commitTransaction(self.AuxCursor) 
    17401728        return ret 
    17411729 
     
    20152003 
    20162004    ## Property getter/setter methods ## 
    2017     def _getAutoCommit(self): 
    2018         return self.BackendObject.getAutoCommitStatus(self) 
    2019  
    2020  
    2021     def _setAutoCommit(self, val): 
    2022         self.BackendObject.setAutoCommitStatus(self, val) 
    2023  
    2024  
    20252005    def _getAutoSQL(self): 
    20262006        return self.getSQL() 
     
    22532233 
    22542234 
    2255     AutoCommit = property(_getAutoCommit, _setAutoCommit, None, 
    2256             _("Do we need explicit begin/commit/rollback commands for transactions?  (bool)")) 
    2257  
    22582235    AutoPopulatePK = property(_getAutoPopulatePK, _setAutoPopulatePK, None, 
    22592236            _("When inserting a new record, does the backend populate the PK field?")) 
  • trunk/dabo/db/dbFirebird.py

    r3303 r3314  
    194194    def beginTransaction(self, cursor): 
    195195        """ Begin a SQL transaction.""" 
    196         if not cursor.connection._has_transaction(): 
    197             cursor.connection.begin() 
     196        if not self._connection._has_transaction(): 
     197            self._connection.begin() 
    198198            dabo.dbActivityLog.write("SQL: begin") 
    199199 
     
    203203        to the database written to disk. 
    204204        """ 
    205         cursor.connection.commit() 
     205        self._connection.commit() 
    206206        dabo.dbActivityLog.write("SQL: commit") 
    207207 
  • trunk/dabo/db/dbMySQL.py

    r3303 r3314  
    55except ImportError: 
    66    decimal = None 
     7import dabo 
    78from dabo.dLocalize import _ 
    89from dBackend import dBackend 
     
    5960        import MySQLdb.cursors as cursors 
    6061        return cursors.DictCursor 
     62 
     63 
     64    def beginTransaction(self, cursor): 
     65        """ Begin a SQL transaction.""" 
     66        cursor.execute("START TRANSACTION") 
     67        dabo.dbActivityLog.write("SQL: begin") 
     68 
     69 
     70    def commitTransaction(self, cursor): 
     71        """ Commit a SQL transaction.""" 
     72        cursor.execute("COMMIT") 
     73        dabo.dbActivityLog.write("SQL: commit") 
     74 
     75 
     76    def rollbackTransaction(self, cursor): 
     77        """ Rollback a SQL transaction.""" 
     78        cursor.execute("ROLLBACK") 
     79        dabo.dbActivityLog.write("SQL: rollback") 
    6180 
    6281 
  • trunk/dabo/db/dbPostgreSQL.py

    r3303 r3314  
    1414        #self.dbModuleName = "PgSQL" 
    1515        self.dbModuleName = "psycopg" 
    16         self.useTransactions = True  # this does not appear to be required 
    1716        self.conn_user = '' 
    1817 
     
    223222        """ 
    224223        self.commitTransaction(cursor) 
    225          
     224 
     225 
    226226    def getLastInsertID(self, cursor): 
    227227        """ Return the ID of the last inserted row, or None. 
  • trunk/dabo/db/dbSQLite.py

    r3303 r3314  
    33import os 
    44import re 
     5import dabo 
    56from dabo.dLocalize import _ 
     7from dabo.dException import dException 
    68from dBackend import dBackend 
    79from dNoEscQuoteStr import dNoEscQuoteStr as dNoEQ 
     
    7072     
    7173     
    72     def setAutoCommitStatus(self, cursor, val): 
    73         """SQLite doesn't use an 'autocommit()' method. Instead, 
    74         set the isolation_level property of the connection. 
    75         """ 
    76         if val: 
    77             self._connection.isolation_level = None 
    78         else: 
    79             self._connection.isolation_level = "" 
    80         self._autoCommit = val 
    81          
    82      
    8374    def beginTransaction(self, cursor): 
    8475        """ Begin a SQL transaction. Since pysqlite does an implicit 
    85         'begin' even when not using autocommit, simply do nothing. 
     76        'begin' all the time, simply do nothing. 
    8677        """ 
     78        dabo.dbActivityLog.write("SQL: begin (implicit, nothing done)") 
    8779        pass 
    88      
     80 
     81 
     82    def commitTransaction(self, cursor): 
     83        """ Commit a SQL transaction.""" 
     84        try: 
     85            cursor.execute("COMMIT") 
     86            dabo.dbActivityLog.write("SQL: commit") 
     87        except Exception, e: 
     88            if "no transaction is active" in str(e): 
     89                pass 
     90            else: 
     91                dabo.dbActivityLog.write("SQL: commit failed: %s" % e) 
     92                raise dException.DBQueryException, e             
     93 
     94 
     95    def rollbackTransaction(self, cursor): 
     96        """ Rollback a SQL transaction.""" 
     97        cursor.execute("ROLLBACK") 
     98        dabo.dbActivityLog.write("SQL: rollback") 
     99 
    89100     
    90101    def flush(self, crs): 
     102        dabo.dbActivityLog.write("SQL: flush") 
    91103        self._connection.commit() 
    92104 
  • trunk/dabo/db/test/test_dCursorMixin.py

    r3054 r3314  
    4646 
    4747    ## - Begin property unit tests - 
    48     def test_AutoCommit(self): 
    49         cur = self.cur 
    50         self.assertEqual(cur.AutoCommit, False) 
    51         try: 
    52             cur.AutoCommit = True 
    53             self.assertEqual(cur.AutoCommit, True) 
    54         except ValueError: 
    55             # Okay; this db didn't allow the setting of AutoCommit. 
    56             self.assertEqual(cur.AutoCommit, False) 
    57  
    5848    def test_AutoSQL(self): 
    5949        cur = self.cur