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() {
>>>
>>> ..verride
>>> 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 <andru..bjectstyle.org> 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() {
>>>
>>> ..verride
>>> 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 <andru..bjectstyle.org> 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
>>>>
>>>
>>
>>
This archive was generated by hypermail 2.0.0 : Mon Apr 10 2006 - 05:39:06 EDT