Hi,
I agree with almost everything you say.


On 2001.06.28 08:32:18 -0400 Ole Husgaard wrote:
> Hi,
> 
> (Just brainstorming here, sorry if I'm wrong.)
> 
> This algorithm may be fine, but it seems to be for commit
> option A only.
As written, yes, as you point out below, reloading from db for each new
transaction is necessary for B/C
> 
> I think we should also consider the other commit options,

yes

> and optimistic/pessimistic locking.

Not sure why we would want more pessimistic locking-isn't that what we have
now?
> 
> 
> David Jencks wrote:
> > 
> > Hi, the algorithm is in the post marc was replying to.
> > 
> > Here it is again, with garbage collection instructions and referring to
> > entities rather than records.
> > 
> > transactions are numbered sequentially when they are started.
> 
> Sorry, but I don't think we can rely on that if we need
> to avoid dependencies on the transaction service used.
> 
> (By hacking a special dummy XA resource that is
> registered with every new tx seen by JBoss, I
> guess we could get to the Xid, and maintain some
> kind of mapping from the GlobalID to a serial
> number. But that looks a bit ugly to me.)

I agree this is a potential problem.  However I think you don't get
snapshot isolation and maybe you might get more deadlock opportunities
without it. (I think just read committed isolation)  I haven't really
looked into it, but I wondered about using the transaction interceptors--
this is where all new transactions come from, isn't it, and its definitely
part of the container not the TM?
> 
> 
> > Each entity (version) includes the transaction id of the last change to
> it.
> > 
> > When an entity is first loaded from the db, the transaction id of the
> > transaction in which it is loaded is associated with the entity
> version.
> > 
> > When you find an entity (within a transaction), you get the entity
> > version with the largest transaction id <= your transaction id.
> 
> I think a DB load of the entity is needed, if the entity
> has not yet been loaded in that particular transaction.
> You want to see uncommitted changes made from elsewhere
> in the same transaction to the database representation
> of the entity. (That is, if you do _not_ use commit
> option A.)

Agreed
> 
> > When you change an entity, a new version is put in the cache with your
> > transaction id ( of course no one else can see it till you commit: the
> > entity versions need both the transaction sequence and some way of
> telling
> > if they are committed.).
> 
> I guess we could call isModified() after each invocation
> to avoid creating a new version until the entity is
> actually modified.
> But that means that we would use the same entity version
> for different transactions, and since it is too late to
> get the unmodified entity version after isModified()
> returns true, wouldn't we have to create another version
> before the invocation anyway?

After I wrote this I thought about it some more.  I think it can only be
made to work with ejb 2 abstract accessors-- as you say I think for ejb 1.1
beans we need each transaction to get a copy in case they want to modify
something, we can't tell.  I actually don't know if the ejb 2 beans can
store state outside of their abstract accessors.  If so, they too would
need instance/transaction in case whey changed state.  If not, at least
conceptually copy on write is possible.
> 
> > The
> > older versions hang around until no transactions are active that could
> see
> > them, then they are garbage collected. (see below)
> > 
> > There is a transaction property that determines behavior when two
> > transactions try to modify the same entity: either
> > 
> > you get an immediate exception
> > 
> > or
> > 
> > your changes block until the other guy commits (you get an exception)
> or
> > rolls back (your transaction succeeds)
> 
> If we should be optimistic here, I think that we should
> get two different versions of the same entity here, each
> with their own context associated with a different
> transaction.
> 
> If both are changed, the last transaction commit should
> fail, as we might have an unresolvable update conflict.

This is also possible, as soon as the first transaction commits it sets the
other(s) Rollback Only.  Throwing an immediate exception or waiting
prevents the 2nd transaction from wasting time doing work that will be
rolled back if the first transaction commits.  It may also be easier to
keep track of.
> 
> But if one of the entities are not changed, the commit
> of the transaction it is associated with needs no
> database update, and that particular entity version
> can be thrown away at commit time (even if other
> transactions have made (and possibly committed) changes
> to other versions of the same entity).

yes, the blocking/exception is only when 2 transactions try to modify the
same data at once.  Unlimited reads of all versions are fine.
> 
> 
> > Note that only the most recent (committed) version can be modified by
> any
> > transaction, and that the blocking/ exception behavior just described
> only
> > applies to 2 transactions trying to modify the most recent committed
> > version.
> > 
> > Each transaction as it starts is put on an ordered (by transaction
> > sequence) list of active transactions.  When it is committed or rolled
> > back, it is removed.  The first transaction on this list is the oldest
> > active transaction.
> > 
> > The transaction associated with the oldest entity version we have to
> keep
> > around is the oldest interesting transaction.
> > 
> > Lets suppose we have an entity with versions for transactions t1, t7,
> > t11,...
> > 
> > We can discard the version for t1 when the oldest active transaction is
> at
> > least t7, because all transactions that could possibly reference that
> > version have completed.
> > 
> > Note that this results in snapshot transaction isolation rather than
> read
> > committed. (I don't know how read committed is implemented, and don't
> know
> > why you would want to use it). I confess I don't quite understand how
> > snapshot differs from serializable isolation -- its certainly close.
> > 
> > This requires a version for each modifying transaction, rather than a
> > single version or a version for each transaction.  You may need to keep
> > several committed versions around at once until all transactions
> > referencing them are complete.
> 
> I don't think we need this strict ordering of
> transactions.
> 
> If we want to do optimistic transaction locking, we
> need a cache that supports multiple versions of each
> entity (one for each transaction that the entity is
> participating in).

Well, not necessarily, if we can manage copy on write we just need one copy
for each different version.
> 
> If we have that, and use commit option A, we just need
> a reference to the version last committed. However, if
> we pick that version to use in a tx, we might need to
> clone it, as we may need it again for yet another tx.
> 

I think this results in read committed isolation, which is kind of
inconsistent with the idea of a transaction.  Keeping track of transaction
ordering results in much stronger snapshot isolation.
> 
> > Interbase versioning is per transaction , not per query.
> 
> I think we need per-transaction versioning in the cache
> too, if we should support this and/or optimistic locking.
> 
> 
> Best Regards,
> 
> Ole Husgaard.
> 
> _______________________________________________
> Jboss-development mailing list
> [EMAIL PROTECTED]
> http://lists.sourceforge.net/lists/listinfo/jboss-development
> 


_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to