geronimo-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From James Richardson <ja...@time4tea.net>
Subject Geronimo Transaction Management - not spec compliant?
Date Sun, 21 Jan 2007 18:53:27 GMT
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?

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