Re: No access to getObjectStore().getFlattenedInserts() / getFlattenedDeletes()

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Tue Jan 03 2006 - 18:53:28 EST

  • Next message: Andrus Adamchik: "Re: nvarchar / nclob"

    On Jan 2, 2006, at 10:11 PM, Mike Kienenberger wrote:
    > Just a note that moving my AuditLogger class into cayenne.access was
    > enough to use cayenne unmodified, which is one less support nightmare
    > to deal with :)

    Very cool. This removes the urgency.

    > I'm still interested in helping to get support for auditing built-in,
    > once I understand the two-phase commit strategy.

    I opened CAY-414 to track it. I don't think I have a full picture
    myself, but here is how I see the direction.

    Minimal solution would be doing a regular single-phase commit adding
    a custom InsertBatchQuery with audit data in
    TransactionDelegate.willCommit. The only challenge here is to collect
    the data at the right point.

    Fancier solution would be to use DataObjects to store audit instead
    of InsertBatchQuery, but do not register them in the DataContext at
    first. Regarding two-phase commit - as you may see from
    DataContextCommitAction, it invariably creates a new transaction. If
    we can make it behave like a select query (i.e. if there is an
    existing transaction bound to the current thread, use it instead of
    starting its own. This way you can subclass a DataContext to do audit
    like that:

    class MyDC extends DataContext {
        public void commitChanges() {
            Transaction t = context
                             .getParentDataDomain()
                             .createTransaction();

            Transaction.bindThreadTransaction(t);

            try {
                // phase 1 - commit real changes at the
                // DataContext level and flush them to db without commit
                super.commitChanges();

                // phase 2 - register audit objects with data context and
    commit again
                ...
                super.commitChanges();

                // commit entire transaction ...
                // depending on how we change DataContextCommitAction,
                // we will likely need to handle exceptions and rollback
    here as well
                if(transaction.getStatus() == Transaction.STATUS_ACTIVE) {
                   transaction.commit();
                }
            }
            finally {
               Transaction.bindThreadTransaction(null);
            }
        }
    }

    Again I am not yet sure how to split this between core Cayenne and
    custom extensions (that we may provide as an example on Wiki). At the
    minimum DataContextCommitAction needs to avoid its own transaction
    handling if the current thread has a bound transaction.

    Andrus



    This archive was generated by hypermail 2.0.0 : Tue Jan 03 2006 - 18:53:30 EST