1 2 Previous Next 19 Replies Latest reply: Mar 25, 2012 9:10 AM by redfoxlee RSS

When transaction timeout, rollback didn't work as expected.

redfoxlee Newbie

Hi, i got some problem with transaction timeout, hope somebody can help me to figure it out.

 

here is what i'm trying to do :

 

// consider this method as one transaction

method() {

    1.insert table1

    2.insert table2

    3.insert table3

    ....

}

Sometimes this operation could take a very long while until transaction timeout exception occured. and i got something like below:

 

ErrorLogType1

WARN - Abort of action id -3f57cb74:c9a4:499eb149:a92 invoked while multiple threads active within it.

WARN - CheckedAction::check - atomic action -3f57cb74:c9a4:499eb149:a92 aborting with 1 threads active!

 

ErrorLogType2

  The transaction is not active!

  at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1379)

  at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:135)

  at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:87)

 

as it was mentioned before : https://community.jboss.org/wiki/TxMultipleThreads

 

ErrorLogType1 happened between 2 and 3, and ErrorLogType2 happend after 3. Rollback only effected part 1,2 , after that didn't get rolled back.

 

I know maybe i have to increase default transaction-timeout value larger to fit requirement. But in case of it could happen again, i would like to know if there are some solutions for this situation.

 

So, my question is:

 

1. Is this partly rollback a right behavior?

2. If not how can i do to correct this wrong behavior? or how to get completly rollback for this situation?

 

ps:hope my bad english will not get you confused. I will be appreciate for any help. Thank you very much

  • 1. Re: When transaction timeout, rollback didn't work as expected.
    Tom Jenkinson Master

    As I understand what you are saying is:

     

    begin();

    update1();

    update2();

    update3(); <-- WARNS APPEAR DURING THE UPDATE FROM THE TRANSACTION REAPER THREAD

    commit(); <-- INACTIVE EXCEPTION RAISED

     

     

    i.e. Sometimes during update3 you see the rollback happening because the transaction timed out:

    WARN When transaction timeout, rollback didn't work as expected. When transaction timeout, rollback didn't work as expected. - Abort of action id -3f57cb74:c9a4:499eb149:a92 invoked while multiple threads active within it.

    WARN When transaction timeout, rollback didn't work as expected. When transaction timeout, rollback didn't work as expected. - CheckedAction::check - atomic action -3f57cb74:c9a4:499eb149:a92 aborting with 1 threads active!

     

    When you see that message, commit fails with the stack you pasted:

    com.arjuna.ats.internal.jta.transaction.arjunacore.inactive

      com.arjuna.ats.internal.jta.transaction.arjunacore.inactive The transaction is not active!

      at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1379)

      at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:135)

      at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:87)

     

    This all seems normal to me for a transaction that has timed out. Based on what you are saying, I would say that update1, update2 and update3 should all be rolled back, is that what you are seeing? If so, the only correction is to increase the timeout, this would be the same with any transaction manager.

     

    Hope that clarifies,

    Tom

  • 2. Re: When transaction timeout, rollback didn't work as expected.
    redfoxlee Newbie

    Hi, tom. Thank you for you reply, first.

    Based on what you are saying, I would say that update1, update2 and update3 should all be rolled back, is that what you are seeing?

    Yes, this is what i believed. Only just i didn't see the completely rollback for all 3 processes as i expected .

     

    I'm sorry. Again, 3 processes should all be rolled back, right? Did i take it wrong about your answer ? But why they weren't ? Only 2 of them get rolled back, 3rd couldn't.

     

    Based on your reply, i will consider to increase timeout longer than default. In another way, maybe i also should check out why that update query took so long. I mean usually it dosen't take that long (just 1 min for long). Maybe it will take much longer next time, and i have to increase and increase again. it won't end, right?

     

    BTW:we are running this operation on JBoss AS 4.2.2 GA, MySql 5.1 in a VM. OS is REHL 5, Memory 1844MB, Java Heap Memory 1024 MB. any surggestions about this?

     

    Any way thank you again!!

  • 3. Re: When transaction timeout, rollback didn't work as expected.
    Tom Jenkinson Master

    My guess is update3() took place in a different context to the other two activities as the transaction rolled back before update3() really did any work then it either:

    1. update3() was done in a local transaction as the resource manager responsible for update3 could not find transactional info

    2. update3() was done a new JTA transaction as there was no transaction active by the time it was started and therefore automatically committed as it was successful

  • 4. Re: When transaction timeout, rollback didn't work as expected.
    redfoxlee Newbie

    Actually i never used transaction explicity but only call the java method as we usual do.So what i am doing is just like below

     

    private void insertMethod1() {

         execute insert statement;

    }

     

    private void insertMethod2() {

         execute insert statement;

    }

     

    private void insertMethod3() {

         execute insert statement;

    }

     

    public void totalMethod() {

         insertMehthod1();

         insertMehthod2();

         insertMehthod3();

    }

     

    // no annotations

    // no UserTransactions

     

    If i didn't get wrong with this, totalMethod should be treated as one transaction. As i know when there is an RuntimeException was thrown, EJB Container will do the rollback for me.

     

    And the error log like this :

    insertMethod1() excuted

    insertMethod2() excuted

    WARN When transaction timeout, rollback didn't work as expected. When transaction timeout, rollback didn't work as expected. - Abort of action id -3f57cb74:c9a4:499eb149:a92 invoked while multiple threads active within it.

    WARN When transaction timeout, rollback didn't work as expected. When transaction timeout, rollback didn't work as expected. - CheckedAction::check - atomic action -3f57cb74:c9a4:499eb149:a92 aborting with 1 threads active!

    insertMehtod3() excuted

    com.arjuna.ats.internal.jta.transaction.arjunacore.inactive

      com.arjuna.ats.internal.jta.transaction.arjunacore.inactive The transaction is not active!

      at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1379)

      at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:135)

      at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:87)

    After that i checked data, and i found

    • insertMethod1() was rolled back
    • insertMethod2() was rolled back
    • insertMethod3() was not rolled back

     

    I just don't understand why there are only 2 of them get rolled back but the 3rd one. They were in one transaction, isn't it?

    In fact i'm also not familiar with JTA, if there was misunderstanding, please correct me :-)

  • 5. Re: When transaction timeout, rollback didn't work as expected.
    Tom Jenkinson Master

    As the transaction is already rolled back by the time insertMethod3 is called:

     

    private void insertMethod3() {

         execute insert statement;

    }

     

    As the transaction is rolledback by this point, this call is made in a separate (JDBC local) transaction, hence why it commits, i.e. the transaction manager isn't involved in that part of the code execution.

     

    If you were to check, the insertMethod1 and insertMethod2 would have rolled back before insertMethod3 was even called, I would say you should follow the guidance on https://community.jboss.org/wiki/TxMultipleThreads regarding transaction timeout

     

    When you say, no annotations, I assume you have at least some annotation (or XML) to mark this as an EJB?

  • 6. Re: When transaction timeout, rollback didn't work as expected.
    Michael Musgrove Master

    Yes I think Tom has identified what's going. To summarize:

     

    The private EJB methods do not have any default transaction type associated but public void totalMethod() does.

     

    So on entry to totalMethod the container starts a transaction. In insertMethod2() the transaction times out. Therefore when insertMethod3 is called there is no transction and the inserts are done inside a local transaction (ie independant from the one that the container started). Hence, the inserts done in the context of the container managed transaction are rolled back because of the timeout, but the inserts done in the local transaction (in the third method) are committed ok.

     

    I would advise that you set the transaction type on all three methods, then when insertMethod2 returns, an exception should be thrown (because of the timeout) and therefore insertMethod3 will never get called (and you won't end up with partial inserts).

  • 7. Re: When transaction timeout, rollback didn't work as expected.
    Tom Jenkinson Master

    Thanks Mike, I was considering suggesting that (i.e. to mark as transaction mandatory on each of the three update methods) but I am not 100% that that would be enough?

     

    Lets say the transaction is still active imediately prior to calling update3 and update3 is marked as mandatory for a transactions, the EJB is happy therefore to allow the call to proceed.

     

    Lets then say that imediately after entry into update3() the timeout happens but before any SQL is executed. My question is, would the SQL of update3 be ran in its own transaction as, by the time it does the SQL insert, the original transaction is now timed out?

     

    Here is a timeline assuming updateX is marked as mandatory:

     

    begin

     

    call update1

    update1 marked as mandatory so check if transaction exists

    inside update1

    sql insert1

    leaving update1

     

    call update2

    update2 marked as mandatory so check if transaction exists

    inside update2

    sql insert2

    leaving update2

     

    call update3

    update3 marked as mandatory so check if transaction exists

    inside update3

    <TIMEOUT NOW, this rolls back the transaction>

    sql insert3

     

    Question is, is insert3 done in a local transaction or can the container detect the issue and therefore insert3 fails?

     

    Tom

  • 8. Re: When transaction timeout, rollback didn't work as expected.
    redfoxlee Newbie

    When you say, no annotations, I assume you have at least some annotation (or XML) to mark this as an EJB?

    Sorry, my fault. I mean i'm not using any annotations explicity to mark method transactional. (i.e. @TransactionaAttribute)

  • 9. Re: When transaction timeout, rollback didn't work as expected.
    redfoxlee Newbie

    Hi, mike.

    So on entry to totalMethod the container starts a transaction. In insertMethod2() the transaction times out. Therefore when insertMethod3 is called there is no transction and the inserts are done inside a local transaction (ie independant from the one that the container started). Hence, the inserts done in the context of the container managed transaction are rolled back because of the timeout, but the inserts done in the local transaction (in the third method) are committed ok.

    With your summary, all about this are making sense to me now.  Thank you and tom, both of you!

     

    I would advise that you set the transaction type on all three methods, then when insertMethod2 returns, an exception should be thrown (because of the timeout) and therefore insertMethod3 will never get called (and you won't end up with partial inserts).

    You mean annotate them by @TransactionAttribute?

  • 10. Re: When transaction timeout, rollback didn't work as expected.
    Tom Jenkinson Master

    redfoxlee wrote:

     

    When you say, no annotations, I assume you have at least some annotation (or XML) to mark this as an EJB?

    Sorry, my fault. I mean i'm not using any annotations explicity to mark method transactional. (i.e. @TransactionaAttribute)

     

    I assumed as much, that means each method will get the default transactional attribute: REQUIRED.

     

    Making each one MANDATORY will significantly reduce the likelihood of this error happening.

     

    You probably still want to know what happens if the transaction is active as it enters the method, but times out immediately after entering the method.

     

    Also, it definitely sounds like you need to increase the timeout if this is expected to happen a lot!

  • 11. Re: When transaction timeout, rollback didn't work as expected.
    redfoxlee Newbie

    You mean like this ?

    @TransactionAttribute(TransactionAttributeType.MANDATOY)
    insertMethod1();


    @TransactionAttribute(TransactionAttributeType.MANDATOY)
    insertMethod2();

    @TransactionAttribute(TransactionAttributeType.MANDATOY)
    insertMethod3();

    // This one just as usuall way 
    totalMethod() {
          insertMethod1();
          insertMethod2();
          insertMethod3();
    }

    so that insertMethods() become part of totalMethod, one fails others will not even get called? And we don't have to worry about after timeout rest part of them will be performed, right? With no extra exception handling?

  • 12. Re: When transaction timeout, rollback didn't work as expected.
    Tom Jenkinson Master

    Hi redfoxlee,

     

    Two points:

     

    1. I am not certain but those methods might have to be public for that to work

    2. Please note my caveat about being unsure what happens in the following scenario:

     

    call update3

    update3 marked as mandatory so check if transaction exists

    inside update3

    <TIMEOUT NOW, this rolls back the transaction>

    sql insert3

     

    I am still not 100% sure what context the sql insert3 would be done in or whether it would fail. Admittedly this is a very small window of opportunity compared to the current scenario but it is still worth considering.

     

    It sounds like you should be making that change anyway to be fair as that describes clearer what you are attempting to do with these updates.

     

    Tom

  • 13. Re: When transaction timeout, rollback didn't work as expected.
    Tom Jenkinson Master

    Ivo pointed me to this:

     

    http://www.javahelp.info/2009/11/01/using-transactionattribute-in-submethods-on-same-ejb3-beans/

     

    The salient point being:

     

    The reason is that the @TransactionAttribute-annotations will only be honored, if you call the method via a business interface. So the first solutions is to inject the bean itself and call the submethod via the injected bean.

     

    I have to re-iterate, this will only minimize the potential case of the transaction not being active

  • 14. Re: When transaction timeout, rollback didn't work as expected.
    Michael Musgrove Master

    Would it be possible for you to include the AS log for this problem.

     

    Also is it feasible for you to test whether you get the same behaviour on one of the more recent versions of the app server.

1 2 Previous Next