Seam self managed transactions fail?
dreuzel Jan 16, 2008 6:32 AMTransaction problem
I'm updating in bach thousands of independent records.
in a sheduled Seam batch process
I do not want the overhead to start and stop a session for every individual record.
so I prefere the sequence
/hibernate factory creation /get entity manager - session loop begin transaction if error ----- something is wrong in my setup .... process the transaction if error ----- role back this transaction but CONTINUE the loop else flush transactiom if error ----- role back this transaction but CONTINUE the loop else Comit the transaction and hope it seen in the database right away check for more work to do (often wait for predetermened externam messages (response time 1-2 sec but sometines connection problems if connection problem abort the proces and try the whole lot somewhat later endloop
this process runs into many problems:
I use seam 2.0.0.ga quarts as sheduler (works ok)
problem 1: I do not see any updates during the loop (as if the flush doesn't work)
problem 2: as any rollback occurs, the process is dead and I can not recover any information any more
implicitely I lose the whole process.
the rollback rolls-back the full loop.
problem 3: i run into session timeouts after exactly 5 minutes and so
lose the transaction at times
hereby losing everything
using seam i switched of Seam transaction controll / but i still suspect
there is a hidden Seam transaction covering all the loops transaction
-problem 1 and problem 2
as documented I needed to shitch off seam transaction management
transaction-management-enabled="false" in components.xml
?xml version="1.0" encoding="UTF-8"?> <components xmlns="http://jboss.com/products/seam/components" xmlns:core="http://jboss.com/products/seam/core" xmlns:persistence="http://jboss.com/products/seam/persistence" xmlns:drools="http://jboss.com/products/seam/drools" xmlns:async="http://jboss.com/products/seam/async" xmlns:bpm="http://jboss.com/products/seam/bpm" xmlns:security="http://jboss.com/products/seam/security" xmlns:mail="http://jboss.com/products/seam/mail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.0.xsd http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.0.xsd http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.0.xsd http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.0.xsd http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd"> <!-- transaction mangement jpa manual <core:init debug="@debug@" jndi-pattern="@jndiPattern@" />--> <core:init debug="@debug@" jndi-pattern="@jndiPattern@" transaction-management-enabled="false" /> conversation-timeout="12000000" --> <core:manager concurrent-request-timeout="5000000" conversation-timeout="200000000" conversation-id-parameter="cid"/> <persistence:managed-persistence-context name="entityManager" auto-create="true" persistence-unit-jndi-name="java:/httpscanEntityManagerFactory"/> <drools:rule-base name="securityRules"> <drools:rule-files> <value>/security.drl</value> </drools:rule-files> </drools:rule-base> <security:identity authenticate-method="#{authenticator.authenticate}" security-rules="#{securityRules}"/> <event type="org.jboss.seam.notLoggedIn"> <action execute="#{redirect.captureCurrentView}"/> </event> <event type="org.jboss.seam.postAuthenticate"> <action execute="#{redirect.returnToCapturedView}"/> </event> ...
i use JTA and create a delegate session sesson=em.delegate
/hibernate factory creation (allow seam use the JTA EM injection) Session ses=ses=(Session) em.getDelegate();//get the session/get entity manager - session @transaction class.... loop if (ses!=null) txn=ses.beginTransaction();//begin transaction if error ----- something is wrong in my setup .... process the transaction if error ----- catch (Exception er) {result.returnCode=-1;errcod=er; **** String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage(); if (errmsg.indexOf("NullPointerException")>-1) log.error(env+" nullpointer exception failed "+ errmsg,er); else log.error(env+" begin transaction error "+ errmsg); try {//rollback cover if (ses!=null) txn.rollback(); } catch (Exception erx) {errcod=erx; String erxmsg=erx.getClass().getSimpleName() +" err: "+ erx.getMessage(); log.error(env+" Rollback transaction failed "+ erxmsg +" From "+ errmsg); } } else if (ses!=null) ses.flush();//flush transactiom if error -----catch (Exception er) {result.returnCode=-1;errcod=er; String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage(); if (errmsg.indexOf("NullPointerException")>-1) log.error(env+" nullpointer exception failed "+ errmsg,er); else log.error(env+" flush error "+ errmsg); try {//rollback cover if (ses!=null) txn.rollback(); } catch (Exception erx) {errcod=erx; String erxmsg=erx.getClass().getSimpleName() +" err: "+ erx.getMessage(); log.error(env+" Rollback transaction failed "+ erxmsg +" From "+ errmsg); } } else if (ses!=null) txn.commit();//Comit the transaction and hope it seen in the database right away if error ----- catch (Exception er) {result.returnCode=-1;errcod=er; String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage(); if (errmsg.indexOf("NullPointerException")>-1) log.error(env+" nullpointer exception failed "+ errmsg,er); else log.error(env+" comit error "+ errmsg); try {//rollback cover if (ses!=null) txn.rollback(); } catch (Exception erx) {errcod=erx; String erxmsg=erx.getClass().getSimpleName() +" err: "+ erx.getMessage(); log.error(env+" Rollback transaction failed "+ erxmsg +" From "+ errmsg); } } check for more work to do (often wait for predetermened externam messages (response time 1-2 sec but sometines connection problems if connection problem abort the proces and try the whole lot somewhat later endloop
although the error is probably created by a session timeout.
i have no idea how to change the session timeout to more then 5 minutes
Transaction is not active: tx=TransactionImple < ac, BasicAction: a0000c8:453:478ddaee:209 status: ActionStatus.ABORTING >; - nested throwable: (javax.resource.ResourceException: Transaction is not active: tx=TransactionImple < ac, BasicAction: a0000c8:453:478ddaee:209 status: ActionStatus.ABORTING >)
Questions:
1-Why am I not effectifely deacivating (Seam transaction intervention ?)
should be handled since modif of components.xml
-DB not visualy updated by the Flush
2-As a problem of any kind occurs I roll back the last transaction
why is it rolling back the full loop ( dependent on question 1 ?)
3-how do I handle the time out
All help is welcome