![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
|
I'm using psycopg, and accessing a 7.4 database. I get the error mentioned in the subject, and I cannot figure out what the problem is. Roughly, my code reads self.cursor.execute("lock table browse_tally") if self.is_cache_current(): # overlapping update, just release the lock self.store.commit() return self.cursor.execute("delete from browse_tally") ... self.cursor.execute("update timestamps set value=now() where name='browse_tally'") self.store.commit() The psycopg exception I get refers to the "delete from" statement. This fragment is the only code updating the table, but multiple CGI processes may run the same code. I would have expected that the "lock table browse_tally" prevents multiple simultaneous accesses to the table, so that the second attempt at running the same code (which will always regenerate the table from scratch - it's a cache) should block until the previous update completes. For some reason, this does not work. Any insight appreciated. |
#2
| |||
| |||
|
#3
| |||
| |||
|
|
Thanks for the help; with the help of somebody else, I tracked down the problem: There was an additional write (of a time-stamp) to a separate table , so the sequence performed by each writer was this: BEGIN; SELECT value FROM timestamps WHERE name='browse_tally'; /* Make a decision to regenerate the table; if yes: */ LOCK TABLE browse_tally; DELETE FROM browse_tally; /* compute new value of tally, by reading various tables */ COPY TO browse_tally; UPDATE timestamps SET value=NOW() WHERE name='browse_tally'; END; So one process got the browse_tally lock, the other one blocked, still holding a reader lock for the timestamp. When the writer tried to upgrade its reader lock for the timestamps to a writer lock, postgres broke the deadlock. My solution is to change this to BEGIN; SELECT value FROM timestamps WHERE name='browse_tally'; END; BEGIN; /* Make a decision to regenerate the table; if yes: */ LOCK TABLE browse_tally; DELETE FROM browse_tally; /* compute new value of tally, by reading various tables */ COPY TO browse_tally; UPDATE timestamps SET value=NOW() WHERE name='browse_tally'; END; I'm still puzzled that the error is reported when it attempts to perform the DELETE FROM; I would have understood if breaking the deadlock caused the LOCK TABLE to fail. |
![]() |
| Thread Tools | |
| Display Modes | |
| |