ConcurrentModificationError with transactional sessions

59 views
Skip to first unread message

Tim Lesher

unread,
Apr 14, 2008, 2:50:15 PM4/14/08
to sqlalchemy
When I execute this piece of code using a transactional, autoflushing
session against SQLite, I get a ConcurrentModificationError on the
final select:

----------
from sqlalchemy import *
from sqlalchemy.orm import *
eng = create_engine('sqlite://')
sm = sessionmaker(autoflush=True, transactional=True, bind=eng)
session =scoped_session(sm)()

metadata=MetaData()
people_table = Table('people', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(40), nullable=False))
class Person(object): pass
mapper(Person, people_table)
metadata.create_all(bind=eng)

p = Person()
p.name = "Eric"
session.save(p)

p = session.query(Person).filter_by(name="Eric").one()
p.name = "John"

session.rollback()

p = session.query(Person).filter_by(name="Eric").all()
----------


Using a non-transactional session (where the rollback is a no-op), I
have no problem. Turning on SQL echo, I do see something a little
odd--the ORM seems to be holding on to the UPDATE after the rollback.

Interspersing the Python code and the emitted SQL, I see:

----------
p = Person()
p.name = "Eric"
session.save(p)

p = session.query(Person).filter_by(name="Eric").one()

...BEGIN
...INSERT INTO people (name) VALUES (?)
...['Eric']
...SELECT people.id AS people_id, people.name AS people_name
...FROM people
...WHERE people.name = ? ORDER BY people.oid
... LIMIT 2 OFFSET 0
...['Eric']

p.name = "John"

session.rollback()

...ROLLBACK

p = session.query(Person).filter_by(name="Eric").all()
...BEGIN
...UPDATE people SET name=? WHERE people.id = ?
...['John', 1]
...ROLLBACK
Traceback (most recent call last):
[...]
sqlalchemy.exceptions.ConcurrentModificationError: Updated rowcount 0
does not match number of objects updated 1
----------

Is this a bug, or am I misusing the transactional session?

Thanks!

--
Tim Lesher
tle...@gmail.com

Michael Bayer

unread,
Apr 14, 2008, 3:06:01 PM4/14/08
to sqlal...@googlegroups.com

On Apr 14, 2008, at 2:50 PM, Tim Lesher wrote:

>
>
> Is this a bug, or am I misusing the transactional session?
>

until SQLA 0.4.6 is released including a new option called
"autosync=True", which we may combine against the other keyword
options to just create a single value to set along the lines of
"transaction_sync='full'", the Session usually needs to be cleared out
(or at least expire_all() called) after a rollback() occurs.

Tim Lesher

unread,
Apr 14, 2008, 4:15:36 PM4/14/08
to sqlalchemy
On Apr 14, 3:06 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
>
> until SQLA 0.4.6 is released including a new option called  
> "autosync=True", which we may combine against the other keyword  
> options to just create a single value to set along the lines of  
> "transaction_sync='full'", the Session usually needs to be cleared out  
> (or at least expire_all() called) after a rollback() occurs.

Thanks--explicitly clearing out the session after any rollback fixed
the problem.

--
Tim Lesher
tle...@gmail.com
Reply all
Reply to author
Forward
0 new messages