-
1. Re: When transaction timeout, rollback didn't work as expected.
tomjenkinson Mar 22, 2012 3:47 AM (in response to redfoxlee)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 Mar 22, 2012 6:14 AM (in response to redfoxlee)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.
tomjenkinson Mar 22, 2012 6:28 AM (in response to redfoxlee)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 Mar 22, 2012 10:17 AM (in response to tomjenkinson)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.
tomjenkinson Mar 22, 2012 10:34 AM (in response to redfoxlee)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.
mmusgrov Mar 22, 2012 11:16 AM (in response to tomjenkinson)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.
tomjenkinson Mar 22, 2012 11:27 AM (in response to mmusgrov)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 Mar 22, 2012 10:53 PM (in response to tomjenkinson)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 Mar 22, 2012 11:03 PM (in response to mmusgrov)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.
tomjenkinson Mar 23, 2012 2:19 AM (in response to redfoxlee)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 Mar 23, 2012 2:32 AM (in response to tomjenkinson)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.
tomjenkinson Mar 23, 2012 2:36 AM (in response to redfoxlee)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.
tomjenkinson Mar 23, 2012 4:36 AM (in response to tomjenkinson)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.
mmusgrov Mar 23, 2012 7:03 AM (in response to redfoxlee)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.