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
-~----------~----~----~----~------~----~------~--~---

Reply via email to