Dear all,I would put the curs.execute and the conn.commit in separate
unto now I had been thinking this is a wise idiom (in code
that needs not care whether it fails to do what it tries to
do^1):
conn = psycopg2.connection(...)
curs = conn.cursor()
try:
curs.execute(SOME_SQL)
except PSYCOPG2-Exception:
some logging being done, and, yes, I
can safely inhibit propagation^1
finally:
conn.commit() # will rollback, if SOME_SQL failed
conn.close()
So today I head to learn that conn.commit() may very well
raise a DB related exception, too:
psycopg2.errors.SerializationFailure: could not serialize access due to read/write dependencies among transactions
DETAIL: Reason code: Canceled on identification as a pivot, during commit attempt.
TIP: The transaction might succeed if retried.
Now, what is the proper placement of the .commit() ?
(doing "with ... as conn:" does not free me of committing appropriately)
Should I
try:
curs.execute(SOME_SQL)
conn.commit()
except PSYCOPG2-Exception:
some logging being done, and, yes, I
can safely inhibit propagation^1
finally:
conn.close() # which should .rollback() automagically in case we had not reached to .commit()
?
Thanks for insights,
Karsten
ON_LEVEL_SERIALIZABLEunto now I had been thinking this is a wise idiom (in code
that needs not care whether it fails to do what it tries to
do^1):
conn =3D psycopg2.connection(...)
In the above do you have:
https://www.psycopg.org/docs/extensions.html#psycopg2.extensions.ISOLATI=
psycopg2.extensions.ISOLATION_LEVEL_SERIALIZABLE
Or is that in some other concurrent transaction?
()curs =3D conn.cursor()
try:
curs.execute(SOME_SQL)
except PSYCOPG2-Exception:
some logging being done, and, yes, I
can safely inhibit propagation^1
finally:
conn.commit() # will rollback, if SOME_SQL failed
It will if you use with conn:, otherwise it up to you to do the rollback=
Are you are doing a rollback() in except PSYCOPG2-Exception: ?
In the case you show you are doing commit() before the close() so any er=rors in the
transactions will show up then. My first thought would be to wrap the co=mmit() in a
try/except and deal with error there.
Right, and this was suggested elsewhere ;)
And, yeah, the actual code is much more involved :-D
I see that.ifferent then
The question is does the full code you show fail?
The code sample you show in your original post is doing something very d=
what you show in your latest post. At this point I do not understand the=exact problem
we are dealing with.
try:
do something
except:
log something
finally:
.commit()
cadence is fairly Pythonic and elegant in that it ensures the
the .commit() will always be reached regardless of exceptions
being thrown or not and them being handled or not.
On 8/09/24 9:20 am, Karsten Hilbert wrote:
try:
do something
except:
log something
finally:
.commit()
cadence is fairly Pythonic and elegant in that it ensures the
the .commit() will always be reached regardless of exceptions
being thrown or not and them being handled or not.
That seems wrong to me. I would have thought the commit should only
be attempted if everything went right.
What if there's a problem in your code that causes a non-SQL-related exception when some but not all of the SQL statements in the
transaction bave been issued? The database doesn't know something
has gone wrong, so it will happily commit a partially-completed
transaction and possibly corrupt your data.
This is how I normally do things like this:
try:
do something
.commit()
except:
log something
.rollback()
Doing an explicit rollback ensures that the transaction is always
rolled back if it is interrupted for any reason.
On 8/09/24 9:20 am, Karsten Hilbert wrote:
try:
do something
except:
log something
finally:
.commit()
cadence is fairly Pythonic and elegant in that it ensures the
the .commit() will always be reached regardless of exceptions
being thrown or not and them being handled or not.
That seems wrong to me. I would have thought the commit should only
be attempted if everything went right.
What if there's a problem in your code that causes a non-SQL-related exception when some but not all of the SQL statements in the
transaction bave been issued? The database doesn't know something
has gone wrong, so it will happily commit a partially-completed
transaction and possibly corrupt your data.
On 8/09/24 9:20 am, Karsten Hilbert wrote:
try:
do something
except:
log something
finally:
.commit()
cadence is fairly Pythonic and elegant in that it ensures the
the .commit() will always be reached regardless of exceptions
being thrown or not and them being handled or not.
That seems wrong to me. I would have thought the commit should only
be attempted if everything went right.
What if there's a problem in your code that causes a non-SQL-related exception when some but not all of the SQL statements in the
transaction bave been [-- even successfully --] issued?
try:it doesn't technically matter whether I say .commit or .rollback here:
do something
.commit()
except:
log something
.rollback()
Doing an explicit rollback ensures that the transaction is always
rolled back if it is interrupted for any reason.
Am Sat, Sep 07, 2024 at 02:09:28PM -0700 schrieb Adrian Klaver:Unless I'm missing something, the 1st & 3rd versions always do the
We are not dealing with an unsolved problem. I had beenRight, and this was suggested elsewhere ;)I see that.
And, yeah, the actual code is much more involved :-D
The question is does the full code you show fail?
The code sample you show in your original post is doing something very different then
what you show in your latest post. At this point I do not understand the exact problem
we are dealing with.
asking for advice where to best place that .commit() call in
case I am overlooking benefits and drawbacks of choices.
The
try:
do something
except:
log something
finally:
.commit()
cadence is fairly Pythonic and elegant in that it ensures the
the .commit() will always be reached regardless of exceptions
being thrown or not and them being handled or not.
It is also insufficient because the .commit() itself may
elicit exceptions (from the database).
So there's choices:
Ugly:
try:
do something
except:
log something
finally:
try:
.commit()
except:
log some more
Fair but not feeling quite safe:
try:
do something
.commit()
except:
log something
Boring and repetitive and safe(r):
try:
do something
except:
log something
try:
.commit()
except:
log something
I eventually opted for the last version, except for factoring
out the second try: except: block.
Best,
Karsten
--
GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B
t() even afterUgly:
try:
do something
except:
log something
finally:
try:
.commit()
except:
log some more
Fair but not feeling quite safe:
try:
do something
.commit()
except:
log something
Boring and repetitive and safe(r):
try:
do something
except:
log something
try:
.commit()
except:
log something
I eventually opted for the last version, except for factoring
out the second try: except: block.
Unless I'm missing something, the 1st & 3rd versions always do the commi=
the first bit fails, which seems wrong.
I suggest the 1st version but replacing "finally" by "else".=A0 Then the=try-commit-except
will not be executed if the "something" fails.
Perhaps the extra indentation of the second try block is a bit ugly, but=it is more
important that it does the right thing., you may feel
If it is convenient (it may not be) to put the whole thing in a function=
that the follwing is less ugly:
try:
do something
except:
log something
return
try:
.commit()
except:
log some more
return
On 2024-09-08, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
try:
do something
.commit()
except:
log something
.rollback()
What if there's an exception in your exception handler? I'd put the
rollback in the 'finally' handler, so it's always called.
For what it's worth here's the current state of code:
That code doesn't inspire much confidence in me. It's far too
convoluted with too much micro-management of exceptions.
I would much prefer to have just *one* place where exceptions are
caught and logged.
That code doesn't inspire much confidence in me. It's far too
convoluted with too much micro-management of exceptions.
I would much prefer to have just *one* place where exceptions are
caught and logged.
Sysop: | Tetrazocine |
---|---|
Location: | Melbourne, VIC, Australia |
Users: | 4 |
Nodes: | 8 (0 / 8) |
Uptime: | 214:56:14 |
Calls: | 73 |
Calls today: | 1 |
Files: | 21,500 |
Messages: | 73,905 |