geronimo-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Jencks <david_jen...@yahoo.com>
Subject Re: Geronimo Transaction Management - not spec compliant?
Date Mon, 22 Jan 2007 01:49:58 GMT

On Jan 21, 2007, at 10:53 AM, James Richardson wrote:

> Hi,
>
> I recently posted the following to the Spring Support Forum. I  
> wondered if you Geronimo guys would be interested too. I solved the  
> issue by using the JOTM transaction manager, it worked immediately  
> with no problems. - I do need to use Jencks though for its pooled  
> managed connection classes so it would be nice to use the geronimo  
> transaction manager to keep from using so many different packages...
>
> Is the behaviour here compliant, or is is a spring misinterpretation?

I find the text of the jta 1.0.1B spec somewhat unclear on this but I  
notice on p. 63 in the change history for 1.0.1B they changed the  
description of when to call Synchronization.beforeCompletion from  
"before the start of the transaction completion process" to "before  
the start of the two-phase transaction commit process" so I think  
there's at least an implication that we shouldn't call  
beforeCompletion when we know we're going to rollback.

I imagine the problem is that hibernate tries to use something that  
objects because it's set rollbackOnly?

Which version of geronimo is your version of jencks using?

Would you like to file a jira issue for this?

thanks
david jencks

>
> Thanks!
>
> James
>
> --------------------------------
> Hi there,
>
> Would really appreciate a little bit of direction on a problem that  
> has completely got me stuck.
>
> I'm trying to implement Jencks, ActiveMQ, and Hibernate using the  
> Spring HibernateTemplate. I have successfully got activemq  
> delivering messages to the application.
>
> However, when rolling back the transactionmanager's transaction,  
> only the activemq transaction seems to be rolled back, not the  
> hibernate one.
>
> Having spent quite some time looking at this, I find the following  
> behaviour:
>
> I realise that there is a two-phase commit process happening, but  
> am seeing something that doesn't quite seem to look right. Perhaps  
> this is a red herring...
>
> Within a JCA transaction, I call rollback() or setRollbackOnly().  
> Eventually the thread's stack looks like this:
>
> beforeCommit (SpringSessionSynchronization)
> beforeCompletion (SessionFactoryUtils$StateSessionSynchronization)
> beforeCompletion (SessionFactoryUtils$JtaSessionSynchronization)
> beforeCompletion (org.apache.geronimo.transaction.manager.Transacti  
> onImpl)
> rollback (org.apache.geronimo.transaction.manager.Transacti  
> onManagerImpl)
>
> So, it looks like on a rollback(), the beforeCompletion() method is  
> being called... Geronimo is doing this. Is it doing the right thing?
>
> Thanks for any help!
>
> James
>
>
> ---------------------------------
> Without posting all the configuration - which is a little complex  
> to extract (but can do later if needs be) - it seems that the  
> comments in the SessionFactoryUtils$JtaSessionSynchronization do  
> not match up with observed behaviour. I'm wondering if this is why  
> the hibernate session gets committed, when the transaction is in  
> rollback mode.
>
> I wrote a little testcase to show how what happens when the  
> transaction is rolled back, and can't match this up with the Spring  
> behaviour. I am not an expert on any of this by a long way - so may  
> be missing the point completely.
>
> So I guess I'm asking, does this seem like a misconfiguration on my  
> part - or does it look like a bug (either in spring or geronimo)?
>
> Thanks once again.
>
> James
>
>
> From [B]SessionFactoryUtils$JtaSessionSynchronization[/B]
> [code]
>    /**
>         * JTA beforeCompletion callback: just invoked on commit.
>         * <p>In case of an exception, the JTA transaction gets set  
> to rollback-only.
>         * (Synchronization.beforeCompletion is not supposed to  
> throw an exception.)
>         * @see SpringSessionSynchronization#beforeCommit
>         */
>        public void beforeCompletion() {
>            try {
>                boolean readOnly =  
> TransactionSynchronizationManager.isCurrentTransactionReadOnly();
>                this.springSessionSynchronization.beforeCommit 
> (readOnly);
>            }
>            catch (Throwable ex) {
>                logger.error("beforeCommit callback threw  
> exception", ex);
>                try {
>                    this.jtaTransactionManager.setRollbackOnly();
>                }
>                catch (SystemException ex2) {
>                    logger.error("Could not set JTA transaction  
> rollback-only", ex2);
>                }
>            }
>            // Unbind the SessionHolder from the thread early, to  
> avoid issues
>            // with strict JTA implementations that issue warnings  
> when doing JDBC
>            // operations after transaction completion (e.g.  
> Connection.getWarnings).
>            this.beforeCompletionCalled = true;
>            this.springSessionSynchronization.beforeCompletion();
>        }
>
>
>
> [/code]
>
> [B]Testcase [/B]
> [code]
>    public void testFindOutHowSynchronizationWorks() throws Exception {
>        final GeronimoTransactionManager transactionManager =  
> createTxManager();
>
>        transactionManager.begin();
>
>        Transaction transaction = transactionManager.getTransaction();
>
>        transaction.registerSynchronization(new Synchronization() {
>            public void beforeCompletion() {
>                System.out.println 
> ("HibernateTransactionsTest.beforeCompletion");
>                printStatus(transactionManager);
>            }
>
>            public void afterCompletion(int i) {
>                System.out.println 
> ("HibernateTransactionsTest.afterCompletion");
>                printStatus(transactionManager);
>            }
>        });
>
>        transactionManager.rollback();
>    }
>
>    private void printStatus(TransactionManager transactionManager) {
>        int status = 0;
>        try {
>            status = transactionManager.getTransaction().getStatus();
>        } catch (SystemException e) {
>            System.out.println("???" + e.toString());
>        }
>        switch (status) {
>
>            case Status.STATUS_ACTIVE:
>                System.out.println("active");
>                break;
>            case Status.STATUS_ROLLEDBACK:
>            case Status.STATUS_ROLLING_BACK:
>            case Status.STATUS_MARKED_ROLLBACK:
>                System.out.println("rolling back");
>                break;
>            case Status.STATUS_COMMITTED:
>            case Status.STATUS_COMMITTING:
>                System.out.println("committing");
>                break;
>
>            default:
>                System.out.println("something else " + status );
>        }
>    }
>
>    private GeronimoTransactionManager createTxManager() throws  
> Exception {
>        XidFactoryImpl xidFactory = new XidFactoryImpl();
>        int transactionTimoutSeconds = 10;
>        return new GeronimoPlatformTransactionManager 
> (transactionTimoutSeconds, xidFactory,  
> GeronimoDefaults.createTransactionLog(xidFactory, null), null);
>    }
>
> [/code]
>


Mime
View raw message