works=session.query(Work).filter(tnow-Work.taken<timedelta(minutes=15))
.filter(Work.completed==None).limit(1).with_lockmode(mode='update').update(values)
Shouldn't the above query only perform the update on the limited results
of the query?
Darren
query.update() just issues an UPDATE statement. UPDATE doesn't
support any kind of LIMITing keywords (maybe MySQL does, but thats not
SQL). The Query should really be raising an error here without
emitting any SQL.
>
> Thank you,
>
> So I changed my query to a select/for update. then re-added the
> updated
> rows in the transaction, then committed.
>
>
> works=session.query(Work).filter(tnow-
> Work.taken<timedelta(minutes=60)).
> filter
> (Work.completed==None).limit(1).with_lockmode(mode='update').all()
>
> When I run two instances of the program, the second one will block on
> the query while the first is inside the transaction ('update'). BUT.
> the
> second one should return 1 row when it unblocks because the first
> instance only modified 1 row, leaving the other to satisfy the
> blockers
> query. It doesn't return anything when the transaction is released to
> the second instance. Peculiar.
>
>
> I re-run the second instance after that and it then is able to find
> the
> qualifying row. Is that correct behavior? Both program instances are
> the
> same code.
what I'm not sure about here is if you are expecting the UPDATE to
return the number of rows actually modified, which again is a MySQL
only thing, or the number of rows actually matched. I'm also not
sure if you are updating the rows in such a way that they won't match
after they're updated. So I only have a hazy view of the actual
operation. But from what I'm reading the behavior doesn't sound
correct. Check the SQL log output of both applications which should
illustrate the full conversation.
yeah I understood all that (except for the session.add(row) part,
which doesn't seem related). And no, it does not sound correct, in
that when B is unblocked into the transaction, it should see the same
thing as if it had just been run completely after the A transaction
were committed.
in any case you should view the SQL logs (echo=True) to see what the
conversation is saying. If that all looks as expected, open up two
postgres consoles and try the same conversation manually.