[ZODB-Dev] Webkit Threading and ZODB 3.3a2: problems on Windows

Jeremy Hylton jeremy at zope.com
Thu Feb 19 17:25:43 EST 2004


On Thu, 2004-02-19 at 17:24, Matt Feifarek wrote:
> 1. A servlet either exists, or is instantiated
> 2. As a part of it's building of state, it gets a database connection, 
> and then a handle on an object in the db
> 3. If no changes are made to the object, no get_transaction().commit() 
> is run
>        (we know if changes are made, with good certainty)

You can ask for certain whether changes were made and avoid any question
of your own certainty.

> 4. If changes ARE made, we do call get_transaction().commit()
> 5. Before the servlet "shuts down" we assign the references to the 
> object, to the root, to the connection all to None (but we do NOT 
> delattr() them...)

You should actually close the connection -- call the close() method.  

Just before you close the connection, add some variant of this code

    assert not get_transaction()._objects

The _objects attribute stores all the objects registered with the
transaction.  If you haven't modified anything, the list will be empty. 
If you have modified something, the assertion will fail.

> 6. The servlet is removed back to the pool, waiting to be deployed into 
> a different thread
>        (there should be no object references or root or connection 
> references at this point)

How does the servlet get its original reference to the connection?  I
assume it calls the open() method on the database at the start of each
request.  (Just checking, because I haven't seen any code.)

> I don't understand how there could be any transaction confusion. How 
> could one "transaction" stay around from one servlet lifecycle to the 
> next? Why would it stay in the thread if it was never used or after it 
> was commited? I have seen that connection instances are re-used when you 
> get a "new" one... but only one of two things can happen: no changes 
> have been made (therefore no "transaction", right?) OR changes are made 
> and IMMEDIATELY after, we commit() the transaction.
> 
> Somewhere in there lies my misunderstanding: do "transactions" stay 
> around, even after they are committed? And are there "transactions" that 
> exist even if no data has been changed? If there are, so what? Why does 
> code have to treat them so lightly if it didn't actually do anything?

Transactions begin implicitly but are terminated explicitly.  When 1) a
thread calls get_transaction() or whenever a persistent object is
modified and 2) a transaction does not already exist, a new transaction
is created.  Note that the mechanism in the modification case is for the
connection to call get_transaction().  If a transaction already exists
when you call get_transaction(), it is used.

The transaction is normally associated with a thread.  If a thread
begins a transaction but does not finish it, then subsequent calls to
get_transaction() will return the old, in-progress transaction.

Jeremy





More information about the ZODB-Dev mailing list