Sub transactions in objectstore don't work properly

Issue #78 resolved
Former user created an issue

(sorry for my poor English)

This is a simple code:

from sqlalchemy import *

engine = create_engine('sqlite', {'filename': ':memory'})

users = Table('users', engine, 
  Column('user_id', Integer, primary_key = True),
  Column('name', String(20)),
  )
users.create()

objectstore.LOG=True

class User(object):
  pass

assign_mapper(User, users)

t = objectstore.begin()
u = User()
tt = t.begin()
u.name = 'test'
tt.rollback()
print 'First transaction done'
tt = t.begin()
u.name = 'test'
tt.commit()
print 'Second transaction done'

And this is the output:

First transaction done
Task dump:
 UOWTask(1078963660) 'User/users/1078961740'
  |
  |- Save elements
  |- Save: UOWTaskElement(1078963756): User(1078963180) (save)
  |----



Execute complete (no post-exec changes)

Second transaction done

It seems from the second sub transaction up commits are performed separately from the parent transaction.

This problem is encountered with file-based SQLite databases too.

Comments (2)

  1. Mike Bayer repo owner
    • marked as
    • changed component to orm

    performing the tt.rollback() should invalidate the entire transaction, i.e. "t" and "tt" are no-ops after that. so there should be no commit at all, and begin() after the rollback() should raise an exception.

    Ill look into making the "trans" object more predictable with regards to rollbacks.

    also, you should figure out exactly what "nesting" scenario youre looking for, since theres more than one. the current scenario allows for basically just one transaction, even though you can call begin multiple times, all begin's after the first do nothing. this is how a regular DB works.

    the other scheme is truly "nested" transactions where each begin/commit pair writes to the database, regardless of another begin/commit pair that might be enclosing it. I had it this way originally since that seemed like it might be useful. the logic for this is simple and can possibly be an optional behavior.

    but my own apps i havent even gotten into begin/commit so much, im just doing objectstore.clear() / objectstore.commit() and thats it. most users seem to like option #1 better (which is also how ive done it in the past).

  2. Log in to comment