users@glassfish.java.net

genericra transaction still tries to complete after setRollbackonly - help

From: <glassfish_at_javadesktop.org>
Date: Wed, 25 Jul 2007 10:04:41 PDT

Hi,

I'm using tibco ems, genericra, and hibernate, with sun appserver / glassfish 8.01 b02.

When a "bad" message comes in, the application is calling setrollbackonly on the MessageDrivenContext, however from the logs it looks like the server is still trying to commit the tx.

code snippet:

    Logger log = Logger.getLogger(getClass().getName());
    
    @Resource
    MessageDrivenContext context;
 
    @Resource(name = "aConnectionFactory")
    ConnectionFactory aConnectionFactory;
 
    @Resource(name = "aTopic")
    Topic aTopic;
 
    @PersistenceContext(unitName = "whatever")
    EntityManager entityManager;
    
    
    private SpecialList myList;
    
    @PostConstruct
    public void initialise() {
        myList= new PersistentSpecialList(entityManager);
    }
    
    public void onMessage(Message message) {
        try {
            Connection connection = aConnectionFactory.createConnection();
            try {
                Session session = connection.createSession(true, SESSION_TRANSACTED);
                try {
                    MessageProducer producer = session.createProducer(aTopic);
                    try {
                        
                        TransactomaticMessageReceiver jmsMessageReceiver = ...
                        
                        jmsMessageReceiver.receive(message);
                    }
                    finally {
                        producer.close();
                    }
                }
                finally {
                    session.close();
                }
            }
            finally {
                connection.close();
            }
            
        } catch (RuntimeException e) {
            log.log(SEVERE, "Defect", e);
            context.setRollbackOnly();
            
        } catch (JMSException e) {
            context.setRollbackOnly();
            log.log(SEVERE, "JMS Failed", e);
        }
    }




However when i send in a bad message I get this in the logs (repeated forever as the provider will keep sending the message - meaning the system is poisoned)

[

#|2007-07-25T15:45:30.651+0100|INFO|sun-appserver-pe9.0|javax.enterprise.system.container.ejb.mdb|_ThreadID=15;_ThreadName=p: thread-pool-1; w: 5;|javax.ejb.EJBException
javax.ejb.EJBException: Transaction aborted; nested exception is: javax.transaction.RollbackException
javax.transaction.RollbackException
        at com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:298)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.commit(J2EETransactionManagerImpl.java:999)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:383)
        at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3653)
        at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3431)
        at com.sun.ejb.containers.MessageBeanContainer.afterMessageDeliveryInternal(MessageBeanContainer.java:1112)
        at com.sun.ejb.containers.MessageBeanContainer.afterMessageDelivery(MessageBeanContainer.java:1083)
        at com.sun.ejb.containers.MessageBeanListenerImpl.afterMessageDelivery(MessageBeanListenerImpl.java:66)
        at com.sun.enterprise.connectors.inflow.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:126)
        at $Proxy40.afterDelivery(Unknown Source)
        at com.sun.genericra.inbound.InboundJmsResource.releaseEndpoint(InboundJmsResource.java:182)
        at com.sun.genericra.inbound.WorkImpl.run(WorkImpl.java:57)
        at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:63)
        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:479)
javax.ejb.EJBException: Transaction aborted; nested exception is: javax.transaction.RollbackException
        at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3659)
        at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3431)
        at com.sun.ejb.containers.MessageBeanContainer.afterMessageDeliveryInternal(MessageBeanContainer.java:1112)
        at com.sun.ejb.containers.MessageBeanContainer.afterMessageDelivery(MessageBeanContainer.java:1083)
        at com.sun.ejb.containers.MessageBeanListenerImpl.afterMessageDelivery(MessageBeanListenerImpl.java:66)
        at com.sun.enterprise.connectors.inflow.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:126)
        at $Proxy40.afterDelivery(Unknown Source)
        at com.sun.genericra.inbound.InboundJmsResource.releaseEndpoint(InboundJmsResource.java:182)
        at com.sun.genericra.inbound.WorkImpl.run(WorkImpl.java:57)
        at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:63)
        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:479)
|#]
 
[#|2007-07-25T15:45:33.103+0100|WARNING|sun-appserver-pe9.0|javax.enterprise.system.core.transaction|_ThreadID=16;_ThreadName=p: thread-pool-1; w: 6;_RequestID=b6ca3892-1047-4ef9-94c2-711dd7a664e2;|JTS5054: Unexpected error occurred in after completion
javax.persistence.EntityExistsException: org.hibernate.exception.ConstraintViolationException: could not insert: [com.xxxx.bp.laser.model.SettledTradeTodoItem]
        at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:605)
        at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:525)
        at com.sun.jts.jta.SynchronizationImpl.before_completion(SynchronizationImpl.java:86)
        at com.sun.jts.CosTransactions.RegisteredSyncs.distributeBefore(RegisteredSyncs.java:143)
        at com.sun.jts.CosTransactions.TopCoordinator.beforeCompletion(TopCoordinator.java:2529)
        at com.sun.jts.CosTransactions.CoordinatorTerm.commit(CoordinatorTerm.java:263)
        at com.sun.jts.CosTransactions.TerminatorImpl.commit(TerminatorImpl.java:234)
        at com.sun.jts.CosTransactions.CurrentImpl.commit(CurrentImpl.java:608)
        at com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:296)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.commit(J2EETransactionManagerImpl.java:999)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:383)
        at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3653)
        at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3431)
        at com.sun.ejb.containers.MessageBeanContainer.afterMessageDeliveryInternal(MessageBeanContainer.java:1112)
        at com.sun.ejb.containers.MessageBeanContainer.afterMessageDelivery(MessageBeanContainer.java:1083)
        at com.sun.ejb.containers.MessageBeanListenerImpl.afterMessageDelivery(MessageBeanListenerImpl.java:66)
        at com.sun.enterprise.connectors.inflow.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:126)
        at $Proxy40.afterDelivery(Unknown Source)
        at com.sun.genericra.inbound.InboundJmsResource.releaseEndpoint(InboundJmsResource.java:182)
        at com.sun.genericra.inbound.WorkImpl.run(WorkImpl.java:57)
        at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:63)
        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:479)
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [com.xxxx.bp.laser.model.SettledTradeTodoItem]
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2267)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2660)
        at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:56)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
        at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:516)
        ... 20 more
Caused by: java.sql.SQLException: ORA-01400: cannot insert NULL into ("LASER"."SETTLEDTRADETODOITEM"."BORROWERSHORTNAME")
 
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
        at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
        at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:955)
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1169)
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3285)
        at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3368)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2250)
        ... 30 more
|#]


I can see the choice point here BaseContainer line 3610:

   int status = transactionManager.getStatus();
        if ( status == Status.STATUS_NO_TRANSACTION ) {
            // no tx was started, probably an exception was thrown
            // before tm.begin() was called
            return newException;
        }
        
        if ( isSession && !isStatelessSession )
            ((SessionContextImpl)context).setTxCompleting(true);
        
        // A new tx was started, so we must commit/rollback
        if ( newException != null
        && isSystemUncheckedException(newException) ) {
            // EJB2.0 section 18.3.1, Table 15
            // Rollback the Tx we started
            try {
                forceDestroyBean(context);
            } finally {
                transactionManager.rollback();
            }
            newException = processSystemException(newException);
        }
        else {
            try {
                if ( status == Status.STATUS_MARKED_ROLLBACK ) {
                    // EJB2.0 section 18.3.1, Table 15, and 18.3.6:
                    // rollback tx, no exception
                    if (transactionManager.isTimedOut()) {
                        _logger.log(Level.WARNING, "ejb.tx_timeout",
                                    new Object[] {
                            transactionManager.getTransaction(),
                                ejbDescriptor.getName()});
                    }
                    transactionManager.rollback();
                }

so bit mystified.. any help gladly received.
[Message sent by forum member 'time4tea' (time4tea)]

http://forums.java.net/jive/thread.jspa?messageID=228199