Re: Savepoint or subtransaction support
Markus Schiltknecht <[email protected]> Fri, 06 Oct 2006 11:56:05 +0200
| Newsgroups | gmane.comp.python.db.pypgsql.user |
|---|---|
| Message-ID | <[email protected]> |
This is a MIME-formatted message. If you see this text it means that your E-mail software does not support MIME-formatted messages. --=_molabola.bugaboo.mu-22722-1160128565-0001-2 Content-Type: text/plain; charset=iso-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi, as I really urgently need savepoints, I have written a small patch to add support for one savepoint. Only to find out that I should have looked in the SF 'patches' page where someone else did exactly the same... I'm comparing our patches just now. Regards Markus Markus Schiltknecht wrote: > Hi, > > I'd like to use savepoints or subtransactions. Now PyPgSQL does not seem > to support them. > > Searching through the archives brought up a bug [1] and a feature > request at [2] for savepoint support. Another guy run into the same > problem as I did, but his solution seems dubious, see [3]. > > What's PyPgSQL's state concerning subtransactions or savepoints? What > does the Python DB-API say about them? What do other (i.e. MySQL > interfaces) do? > > Regards > > Markus > > > [1]: Bug: > https://sourceforge.net/tracker/index.php?func=detail&aid=1409818&group_id=16528&atid=116528 > > [2]: Feature Request: > https://sourceforge.net/tracker/index.php?func=detail&aid=1503756&group_id=16528&atid=366528 > > [3]: Don't use transactions > https://sourceforge.net/tracker/index.php?func=detail&aid=1524586&group_id=16528&atid=116528 > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share your > opinions on IT & business topics through brief surveys -- and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > Pypgsql-users mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/pypgsql-users --=_molabola.bugaboo.mu-22722-1160128565-0001-2 Content-Type: text/plain; name=diff; charset=iso-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diff" Index: pyPgSQL/PgSQL.py =================================================================== RCS file: /cvsroot/pypgsql/pypgsql/pyPgSQL/PgSQL.py,v retrieving revision 1.50 diff -c -r1.50 PgSQL.py *** pyPgSQL/PgSQL.py 1 Jun 2006 14:42:51 -0000 1.50 --- pyPgSQL/PgSQL.py 6 Oct 2006 09:50:42 -0000 *************** *** 2368,2373 **** --- 2368,2374 ---- self.__dict__["TransactionLevel"] = "" self.__dict__["notices"] = self.conn.notices self.__dict__["inTransaction"] = 0 + self.__dict__["current_savepoint"] = 0 self.__dict__["version"] = self.conn.version self.__dict__["_isOpen"] = 1 self.__dict__["_cache"] = TypeCache(self) *************** *** 2542,2547 **** --- 2543,2549 ---- self.__dict__["conn"] = None self.__dict__["cursors"] = None self.__dict__["inTransaction"] = 0 + self.__dict__["current_savepoint"] = 0 self.__dict__["TransactionLevel"] = None self.__dict__["version"] = None self.__dict__["notices"] = None *************** *** 2587,2592 **** --- 2589,2671 ---- raise InternalError, \ "Rollback failed - %s" % res.resultErrorMessage + def savepoint(self, name): + """ + savepoint() + Set a savepoint in the current connection, to which the connection + gets rolled back to on error or on request.\n""" + + if not self._isOpen: + raise InterfaceError, "Savepoint failed - Connection is not open." + + if self.autocommit: + raise InterfaceError, "Savepoint failed - autocommit is on." + + if not self.inTransaction: + raise InterfaceError, "Savepoint failed - not in a transaction." + + _nl = len(self.conn.notices) + res = self.conn.query("SAVEPOINT %s" % name) + if len(self.notices) != _nl: + raise Warning, self.notices.pop() + if res.resultStatus != COMMAND_OK: + raise InternalError, \ + "Savepoint failed - %s" % res.resultErrorMessage + + self.__dict__["current_savepoint"] = name + + def rollback_savepoint(self, name=None): + if not self._isOpen: + raise InterfaceError, "Rollback savepoint failed - Connection is not open." + + if self.autocommit: + raise InterfaceError, "Rollback savepoint failed - autocommit is on." + + if not self.inTransaction: + raise InterfaceError, "Rollback savepoint failed - not in a transaction." + + if not self.current_savepoint: + raise InterfaceError, "Rollback savepoint failed - no savepoint active." + + if not name: + name = self.current_savepoint + + _nl = len(self.conn.notices) + res = self.conn.query("ROLLBACK TO SAVEPOINT %s" % name) + if len(self.notices) != _nl: + raise Warning, self.notices.pop() + if res.resultStatus != COMMAND_OK: + raise InternalError, \ + "Release savepoint failed - %s" % res.resultErrorMessage + + self.__dict__["current_savepoint"] = 0 + + def release_savepoint(self, name=None): + if not self._isOpen: + raise InterfaceError, "Release savepoint failed - Connection is not open." + + if self.autocommit: + raise InterfaceError, "Release savepoint failed - autocommit is on." + + if not self.inTransaction: + raise InterfaceError, "Release savepoint failed - not in a transaction." + + if not self.current_savepoint: + raise InterfaceError, "Release savepoint failed - no savepoint active." + + if not name: + name = self.current_savepoint + + _nl = len(self.conn.notices) + res = self.conn.query("RELEASE SAVEPOINT %s" % name) + if len(self.notices) != _nl: + raise Warning, self.notices.pop() + if res.resultStatus != COMMAND_OK: + raise InternalError, \ + "Release savepoint failed - %s" % res.resultErrorMessage + + self.__dict__["current_savepoint"] = 0 + def cursor(self, name=None, isRefCursor=PG_False): """ cursor([name]) *************** *** 3101,3107 **** except OperationalError, msg: # Uh-oh. A fatal error occurred. This means the current trans- # action has been aborted. Try to recover to a sane state. ! if self.conn.inTransaction: _n = len(self.conn.notices) self.conn.conn.query('ROLLBACK WORK') if len(self.conn.notices) != _n: --- 3180,3188 ---- except OperationalError, msg: # Uh-oh. A fatal error occurred. This means the current trans- # action has been aborted. Try to recover to a sane state. ! if self.conn.current_savepoint: ! self.conn.rollback_savepoint() ! elif self.conn.inTransaction: _n = len(self.conn.notices) self.conn.conn.query('ROLLBACK WORK') if len(self.conn.notices) != _n: --=_molabola.bugaboo.mu-22722-1160128565-0001-2 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys -- and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV --=_molabola.bugaboo.mu-22722-1160128565-0001-2 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Pypgsql-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/pypgsql-users --=_molabola.bugaboo.mu-22722-1160128565-0001-2--