Transaction demarcation problem
dreuzel Jan 22, 2008 8:59 AMi need to update thousands of independent records in sheduled environment.
For efficiency reasons I need to do that in a big loop ( set of loops)
also because the underlying info is externaly organised like that.
I disabled the seam control over transactions
I'm trying to disable container management over transactions
but so far I realy can not Use transaction control in the environment
there is always something wrong !!
If not seen any effect of a flush and I'm losing all the work done
due to the fact I need to rollback a single item transaction
process
Connect external loop update record if (fails) Rollback this ONLY RECORD WITHOUT ANY IMPACT ON THE REST OF THE ENVIRONMENT handle next
It is very important the overall process is not aborted on any individual error.
(this is what is happening in the actual case with a fail rate on 1 on 1000 this means
I never get never nothingthing done !!!!)
at this time I use following code to handle the transaction
as I'm working in a seam environment
I switched to manual transaction handling
and I'm bouncing/fighting against JTA CONTAINER - BEAN managed transactions
code :
@Name("loopscan") @TransactionManagement(TransactionManagementType.BEAN) //kill container management @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) //suspend all active container transactions public class BatchTransactions { // @Logger private Log log; // @In ("#{entityManager}") public EntityManager em;//allow for db ACCESS Session ses=null;//session indicator String env="Init"; // org.hibernate.Transaction txn=null;//hibernate transaction public BatchTransactions() {} public void initTransaction() { } public Exception sequence() { Exception errcod=null; org.hibernate.Transaction txn=null;// boolean rollback=false; //reset timeout try { env="Timeout"; org.jboss.seam.transaction.Transaction.instance().setTransactionTimeout(60*60*10000000); } catch (Exception er) {errcod=er; String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage(); log.error(env+" Modifying timeout failed "+ errmsg); } // seam timeout try { env ="seam timeout"; Transaction.instance().setTransactionTimeout(60*60*10000000);} catch (Exception er) {errcod=er; String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage(); log.error(env+" Modifying Seam timeout failed "+ errmsg); } // //connect to session // env="setup"; ses=(Session) em.getDelegate();//get the session // // transaction with own error handling // try { env="Begin";// Begin the transaction ? txn=ses.getTransaction(); if(!txn.isActive()) txn.begin();// txn=ses.beginTransaction(); ********************** // txn.setTimeout(500000); } catch (Exception er ) {errcod=er; String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage(); log.error(env+" starting transaction failed "+ errmsg); } try {env="execute "; //ececution process errcod=Execute();//do the DB operations try {//flush the info to other users ses.flush(); } catch (Exception er ) {errcod=er;rollback=true; String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage(); log.error("Flush "+env+" Commiting transaction failed "+ errmsg); } try {//commit the information txn.commit(); } catch (Exception er ) {errcod=er;rollback=true; String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage(); if (errmsg.indexOf("NullPointerException")>-1) log.error("Commit "+env+" Commit nullpointer exception failed "+ errmsg,er); else log.error(env+" Commiting transaction failed "+ errmsg); } } catch( GenericJDBCException er) {String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage();rollback=true; // if (errmsg.indexOf("Cannot open connection")>-1) // { if (!em.isOpen()) log.info("Em session still open !"); // try {if (ses==null) {ses=(Session) em.getDelegate();}//get the session // txn=ses.beginTransaction(); log.error(env+" Cannot open connection "+ errmsg,er); } catch (Exception er) {FatalStatus();errcod=er;rollback=true; 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+" overall transaction error "+ errmsg); } if (rollback) try {//rollback cover txn.rollback(); } catch (Exception er) {errcod=er; String errmsg=er.getClass().getSimpleName() +" err: "+ er.getMessage(); log.error("Rollback "+env+" Rollback transaction failed "+ errmsg +" From "+ errmsg); } // // detect losing the session // if (ses==null) { if (!(em.isOpen())) log.info("em session closed !"); } return errcod; } /* */ public void TxnSts(String env) {this.env=env;} public Exception Execute() throws Exception {return null;}; public void FatalStatus() {}; } {
As you can see most of the code is error trapping and reporting
It fails at the BEGIN transaction
stating : TransactionException err: Could not register synchronization for container transaction
The default for the bean is set to BEAN transactions
but still it considers it a Container transaction
any suggestions would be more then welcome