On Nov 30, 2007, at 3:06 PM, imgrey wrote:
> > > On 30 нояб, 21:07, Michael Bayer <[EMAIL PROTECTED]> wrote: >> hey there - >> >> this is line 179 right now: >> >> if bind in conn_dict: >> >> similar mismatches in the stacktrace are present for lines 505 and >> 509 >> (line 505 is a blank line now). >> >> the full snip of code is: >> >> if bind in conn_dict: >> (conn, trans, autoclose) = conn_dict[bind] >> self.__connections[conn] = >> self.__connections[bind.engine] = (conn, conn.begin_nested(), >> autoclose) >> return conn >> >> so my guess is that you arent running the most recent trunk. > > Of course you're right. I'd run script on another host by chance, > sorry. > > There's the output with revision 3846: > > Exception in thread Thread-5: > Traceback (most recent call last): > File "threading.py", line 442, in __bootstrap > self.run() > File "./camper.py", line 122, in run > walk(session, theone, root) > File "./camper.py", line 91, in walk > session.commit() > File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/scoping.py", > line 74, in do > return getattr(self.registry(), name)(*args, **kwargs) > File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/session.py", > line 484, in commit > self.transaction = self.transaction.commit() > File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/session.py", > line 211, in commit > self.session.flush() > File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/session.py", > line 686, in flush > self.uow.flush(self, objects) > File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/ > unitofwork.py", line 207, in flush > flush_context.execute() > File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/ > unitofwork.py", line 434, in execute > UOWExecutor().execute(self, head) > File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/ > unitofwork.py", line 1053, in execute > self.execute_save_steps(trans, task) > File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/ > unitofwork.py", line 1067, in execute_save_steps > self.save_objects(trans, task) > File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/ > unitofwork.py", line 1058, in save_objects > task.mapper.save_obj(task.polymorphic_tosave_objects, trans) > File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/mapper.py", > line 1104, in save_obj > raise exceptions.ConcurrentModificationError("Updated rowcount %d > does not match number of objects updated %d" % (rows, len(update))) > ConcurrentModificationError: Updated rowcount 0 does not match number > of objects updated 1 > OK, the error means, thread #1 has loaded an object into its session. then, thread #2 loads an object into another session. thread #1 deletes the object. Thread #2 then makes its own change on the object and commits; the update fails since the row to be updated no longer exists. one immediate flaw I see in your application is that you are using implicit execution of SQL constructs without them having any connection to the ongoing transaction, such as: f_table.delete(f_table.c.user_id==theone.id).execute() f_table.insert().execute(user_id=theone.id, path='/', ls=ls) When you issue somestatement.execute(), the ClauseElement locates an Engine which is associated with one of the tables in the statement, then locates the connection pool for that engine, and checks out a fresh new connection from the pool with which to execute. this connection has no relationship whatsoever to the transacitons which you are creating with your session, so they will not participate in that transaction. A full set of examples on the proper way to share SQL expressions with your session is described at: http://www.sqlalchemy.org/docs/04/session.html#unitofwork_sql the easiest solution would be to just turn on the "threadlocal=True" flag on your engine, which means that all connection requests in the same thread use the same connection and transaction. So a step like that should help, but the design of your application still seems to require random deletes and updates of data in different threads, and youre also using some really esoteric features such as SAVEPOINT transactions (i.e. via the begin_nested()). If you're using all that and having trouble figuring out how to arrange concurrency properly, its possible that you'd need to simplify your application a bit. If its really just a multithreaded daemon I'd might even try using normal threading.Lock objects to limit access to critical mutable structures. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---