Skip to content

Commit 4328a61

Browse files
committed
Reopen connection when commit or rollback fails, as suggested by Ben Hoyt.
1 parent e027419 commit 4328a61

2 files changed

Lines changed: 70 additions & 2 deletions

File tree

DBUtils/SteadyDB.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,12 +402,32 @@ def begin(self, *args, **kwargs):
402402
def commit(self):
403403
"""Commit any pending transaction."""
404404
self._transaction = False
405-
self._con.commit()
405+
try:
406+
self._con.commit()
407+
except self._failures, error: # cannot commit
408+
try: # try to reopen the connection
409+
con = self._create()
410+
except Exception:
411+
pass
412+
else:
413+
self._close()
414+
self._store(con)
415+
raise error # reraise the original error
406416

407417
def rollback(self):
408418
"""Rollback pending transaction."""
409419
self._transaction = False
410-
self._con.rollback()
420+
try:
421+
self._con.rollback()
422+
except self._failures, error: # cannot rollback
423+
try: # try to reopen the connection
424+
con = self._create()
425+
except Exception:
426+
pass
427+
else:
428+
self._close()
429+
self._store(con)
430+
raise error # reraise the original error
411431

412432
def cancel(self):
413433
"""Cancel a long-running transaction.

DBUtils/Tests/TestSteadyDB.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,13 @@ def close(self):
6262
self.valid = False
6363

6464
def commit(self):
65+
if not self.valid:
66+
raise InternalError
6567
self.session.append('commit')
6668

6769
def rollback(self):
70+
if not self.valid:
71+
raise InternalError
6872
self.session.append('rollback')
6973

7074
def ping(self):
@@ -703,6 +707,50 @@ def test16_ResetTransaction(self):
703707
db.close()
704708
self.assertEqual(db._con.session, ['rollback'])
705709

710+
def test17_CommitError(self):
711+
db = SteadyDBconnect(dbapi, database='ok')
712+
db.begin()
713+
self.assert_(not db._con.session)
714+
self.assert_(db._con.valid)
715+
db.commit()
716+
self.assertEqual(db._con.session, ['commit'])
717+
self.assert_(db._con.valid)
718+
db.begin()
719+
db._con.valid = False
720+
con = db._con
721+
self.assertRaises(InternalError, db.commit)
722+
self.assert_(not db._con.session)
723+
self.assert_(db._con.valid)
724+
self.assert_(con is not db._con)
725+
db.begin()
726+
self.assert_(not db._con.session)
727+
self.assert_(db._con.valid)
728+
db.commit()
729+
self.assertEqual(db._con.session, ['commit'])
730+
self.assert_(db._con.valid)
731+
732+
def test18_RollbackError(self):
733+
db = SteadyDBconnect(dbapi, database='ok')
734+
db.begin()
735+
self.assert_(not db._con.session)
736+
self.assert_(db._con.valid)
737+
db.rollback()
738+
self.assertEqual(db._con.session, ['rollback'])
739+
self.assert_(db._con.valid)
740+
db.begin()
741+
db._con.valid = False
742+
con = db._con
743+
self.assertRaises(InternalError, db.rollback)
744+
self.assert_(not db._con.session)
745+
self.assert_(db._con.valid)
746+
self.assert_(con is not db._con)
747+
db.begin()
748+
self.assert_(not db._con.session)
749+
self.assert_(db._con.valid)
750+
db.rollback()
751+
self.assertEqual(db._con.session, ['rollback'])
752+
self.assert_(db._con.valid)
753+
706754

707755
if __name__ == '__main__':
708756
unittest.main()

0 commit comments

Comments
 (0)