Cris,

you lost me here...

If you have a user transaction manually bound to thread, you'd still have to commit a DataContext via "commitChanges()" which basically does a flush without commit ... and then commit a transaction that does a DB commit (and calls the delegate method).

But I guess the whole point of the delegate is to avoid manual transaction handling. So I am more interested whether Cayenne- initiated transactions work. More specifically if you replace this part of "willCommit" of the delegate:

        transaction.performQueries(dataContext,
Collections.singleton(updateQuery), new DefaultOperationObserver() {

            @Override
            public boolean isIteratedResult() {
                return true;
            }

        });

with this line:

dataContext.performGenericQuery(query);

That's what I meant by "running directly via DataContext"... implying "running directly via DataContext inside 'willCommit' method". Does it work?

Andris




On Apr 10, 2006, at 1:49 AM, Cris Daniluk wrote:
I can run the ProcedureQuery directly via the context, but it is a
committing operation. If I bind a Transaction to the thread, I can get the ProcedureQuery to run in the TransactionDelegate, but only if I commit the
Transaction, and not if I commit the DataContext.

Basically, if I make some objects dirty, then bind a Transaction, then
commit the DataContext, the Transaction is not committed. If I commit the Transaction instead in that scenario, the objects are not flushed. This behavior seemed a little off to me and I was planning on testing in the beta
to see if it still worked that way.

Meanwhile, I have put in place a fairly ugly hack. I have a
LocalTransactionDelegate bound to the DataDomain which looks in a
ThreadLocal Context I have (non-Cayenne) for a TransactionDelegate and
executes it. This way, I can essentially have a ThreadLocal
TransactionDelegate instead of the DataDomain-specific TransactionDelegate.
This allows me to much more cleanly inject stored procedures into the
transaction, and it properly puts the stored procedure execution at the end of the flushed write operations. However, it still doesn't work without
isIteratedResultSet :)

The good news is if I bind a Transaction and then execute the query inside of that, it does not execute the commit, which is the correct behavior. I just have to retest in the beta to see if the other annoying side effects (not flushing the writes first) is fixed. It seems to me like there ought to
be some sort of feature buried in here... something like a
PostFlushProcedureQuery. I think the current behavior is correct in most
cases, but for this particular case, it is a problem.

Oh, and the "LocalTransactionDelegate" is kind of handy too. We could easily add a TransactionDelegate property to the DataContext that was deferred to if the user sets the DataDomain to "LocalTransactionDelegate". I see a lot
of potential applications for that.

Cris

On 4/8/06, Andrus Adamchik <[EMAIL PROTECTED]> wrote:

Cris,

Is this still a problem? Transaction.performQueries(..) is deprecated
and indeed attempts to commit internally. Can you run the
ProcedureQuery directly via DataContext? It should pick up the same
thread transaction.

Andrus



On Feb 28, 2006, at 10:53 PM, Cris Daniluk wrote:

2 weeks later :)

My delegate invokes:

        ProcedureQuery updateQuery = (ProcedureQuery)
dataContext.getEntityResolver().getQuery("MergeDocumentCopy");
        updateQuery.addParameter("documentID", glinID);
        updateQuery.addParameter("userID",
SessionContext.getSessionContext().getSecurityPrincipal().getUserId
());

        transaction.performQueries(dataContext,
Collections.singleton(updateQuery), new DefaultOperationObserver() {

            @Override
            public boolean isIteratedResult() {
                return true;
            }

        });

Note that I am invoking performQueries on the willCommit (Transaction), and not on the context itself. In fact, I'm relatively convinced that
if I were to skip the TransactionDelegate altogether and simply pass
this modified OperationObserver to the dataContext.performQueries, it
would do precisely the right thing.

Perhaps this could be tweaked into cool functionality?

On 2/14/06, Andrus Adamchik <[EMAIL PROTECTED]> wrote:

On Feb 14, 2006, at 6:47 PM, Cris Daniluk wrote:

There are two "official" ways to avoid commit - external
transactions
and user-managed transactions. Can you explain why commit is
undesirable. Is this a standalone ProcedureQuery, or is this
something you are doing from TransactionDelegate?

Running it from a TransactionDelegate. It is happening after a
ton of
insert/updates, but before the overall commit. I would be okay
with it
committing, except that after it commits, the DataContext tries to
again and blows up.

That's very strange. Double commit shouldn't happen. Could you post
the code from the delegate that executes a query?

Andrus





Reply via email to