cancel
Showing results for 
Search instead for 
Did you mean: 

RetryingTransactionHelper learnings

jharrop
Champ in-the-making
Champ in-the-making
The key method in the above is:

   
public <R> R doInTransaction(RetryingTransactionCallback<R> cb, boolean readOnly, boolean requiresNew)

where:

 
     * @param requiresNew       <tt>true</tt> to force a new transaction or
     *                          <tt>false</tt> to partake in any existing transaction.

The other signatures both set requiresNew=false:

 
    public <R> R doInTransaction(RetryingTransactionCallback<R> cb)
    {
        return doInTransaction(cb, false, false);
    }

    public <R> R doInTransaction(RetryingTransactionCallback<R> cb, boolean readOnly)
    {
        return doInTransaction(cb, readOnly, false);
    }
requiresNew is used to set the boolean isNew:

    
           isNew = requiresNew || txn.getStatus() == Status.STATUS_NO_TRANSACTION;
                if (isNew)
                {
                    txn.begin();
                }

The significance of isNew is that RTH only actually retries if isNew

          
    // Somebody else 'owns' the transaction, so just rethrow.
                if (!isNew)
                {
                   logger.info("Someone else owns this transaction " + txn );
                    if (e instanceof RuntimeException)
                    {
                        throw (RuntimeException)e;
                    }
                    else
                    {
                        throw new AlfrescoRuntimeException(
                                "Exception from transactional callback: " + cb,
                                e);
                    }
                }

It seems to me that if you are using RTH, you'll likely want to set requiresNew parameter to true.  If you use one of the simpler method signatures, it is likely RTH won't retry your transaction (which is its raison d'etre?).
5 REPLIES 5

iru
Confirmed Champ
Confirmed Champ

Hi,

Sorry for pumping this up, but have not found many more references related to this topic.

Is RTH supposed to work with 'requiresNew' set to false?

Been debugging code (repo 5.2.f), and when an exception is thrown inside the for loop, it just quits it and does not retry,.. so, don't understand  the utility of having this as a parameter, if it will never do as its name says (retry)

Guess i'm taking something for granted, .. any idea?

afaust
Legendary Innovator
Legendary Innovator

With requiresNew set to false, the retrying transaction helper will look at the current transaction before creating a new transaction. If a transaction is already active no new (nested) transaction will be created. If the existing transaction is incompatible with the requested value of readOnly, an error will be thrown. E.g. if you request a read-write transaction and the current one is a read-only, it will fail. The other way around - a read-only within a read-write - will work though.

If no new transaction is created, the handler cannot apply retrying behaviour. It is assumed that the already active transaction will deal with any retrying semantics in that case.

iru
Confirmed Champ
Confirmed Champ

Hi Axel!

Got that clear from reading the source code of RTH, but if a class is called "Retry Transaction" I would assume that, no matter the parameters, it does what it says, say.. "retry the transaction".

However, the value of the parameter requiresNew, makes the transaction not to retry.

Maybe it's a matter of naming, but I would have expected it to be called "Transaction" and then have a parameter called "retry" (boolean), that if set to true, retries by creating a new transaction.

Does that make sense?

afaust
Legendary Innovator
Legendary Innovator

To some extent it makes sense. As you may know "naming things" is one of the hardest problems in IT. The problem with your example of a "Transaction" class with "retry" parameter set to true is that I may not want the helper to create a new transaction if I am already in one with retrying semantics, so I would somehow have to check the context I am in to determine if I can or cannot use it.

iru
Confirmed Champ
Confirmed Champ

As you said "If no new transaction is created, the handler cannot apply retrying behavior".

Checking source code (5.2.f), this also applies, because when the #execute of the implementation fails with a Throwable, it's just rethrown, without retrying.

community-edition-old/RetryingTransactionHelper.java at master · Alfresco/community-edition-old · Gi... 
So, they're both dependent tasks: retry requires new transaction.