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