Greg Troxel wrote:
> I don't quite understand what is going on.  I think the error happened
> on the INSERT, but on reflection this is because of two similar
> transactions:
> 
>   delete foo if foo is there
>   insert bar
> 
> and the point is that the delete doesn't fail.  Your patch is to try to
> catch the delete failing, and skip the insert.  But I would expect the
> delete to return DELETE 0, which doesn't seem like an error:
> 
> trac-redacted2=# delete from session_attribute where sid = 'no-such-user';
> DELETE 0
> 
> Is this because we are running read committed instead of full
> transactions?  We are having the second transaction to do the insert see
> database state from before the first insert is committed.

Yes you're right. It's the INSERT statement and not the DELETE statement 
that might fail if another transaction manages to execute and commit 
between the DELETE and INSERT of the first transaction (if read 
committed is being used).
I somehow managed to wrap the wrong cursor.execute statement with an 
exception handler.

I've attached an updated version of the patch.

Thanks for spotting this!

/ Jonas


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Trac 
Users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/trac-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Index: trac/web/session.py
===================================================================
--- trac/web/session.py (revision 7647)
+++ trac/web/session.py (working copy)
@@ -97,9 +97,16 @@
                            (self.sid,))
             self._old = dict(self.items())
             if attrs:
-                cursor.executemany("INSERT INTO session_attribute "
-                                   "(sid,authenticated,name,value) "
-                                   "VALUES(%s,%s,%s,%s)", attrs)
+                # The session variables might already have been updated by a 
+                # concurrent request.
+                try:
+                    cursor.executemany("INSERT INTO session_attribute "
+                                       "(sid,authenticated,name,value) "
+                                       "VALUES(%s,%s,%s,%s)", attrs)
+                except Exception, e:
+                    db.rollback()
+                    self.env.log.warning('Attributes for session %s already '
+                                         'updated: %s' % (self.sid, e))
             elif not authenticated:
                 # No need to keep around empty unauthenticated sessions
                 cursor.execute("DELETE FROM session "

Reply via email to