users@glassfish.java.net

Re: Transaction Rollback not working as expected

From: <glassfish_at_javadesktop.org>
Date: Thu, 12 Apr 2007 10:09:03 PDT

Ok, I figured out where the commit point is happening. Whenever you execute a JPA Query, Glassfish is apparently doing a commit. The sequence of steps:

persist an entity
execute EJB Query -- commit is happening here
rollback

According to what I've read in the spec, the entity manager is allowed to/supposed to "flush" changes to the database before executing a query... makes sense. I interpret "flush" as meaning it should execute all needed sql inserts and updates. But it should not be committing the JDBC transaction, which is what appears to be happening

Here is the EJB I wrote specifically to test this problem. After executing, a new record remains in the database.

@Stateless
public class SimpleEntityTestBean implements SimpleEntityTest {

        @PersistenceContext(unitName="application")
        EntityManager em;
        
        @Resource SessionContext session;

        public void testRollback() throws SimpleException {
                
                SimpleEntity se = new SimpleEntity();
                em.persist(se);
                System.out.println("Added SimpleEntity, ID = " + se.getId().toString());
                
                Query q = em.createQuery("SELECT s FROM Sequence s");
                @SuppressWarnings({"unchecked"})
                List<Sequence> results = q.getResultList();

                session.setRollbackOnly();
                throw new SimpleException("ROLLBACK!!!");
        }
}

The source code fragment from my earlier post should be ignored... I was mistaken as to which objects were persisted, the "license" entity was not persisted, but all entities persisted before calling methods on SequenceService were committed.

So, my question now is: Is the JDBC commit before executing the query intentional or a bug?

If it is intentional, how are programmers supposed to safely call one EJB from another? In my application, the EJB called from the web-tier calls other EJBs, some of which are merging and/or persisting entities. All it takes is for one to execute an EJB Query and all prior changes become permanent. In my experience with EJB2 and JBoss, you could call finder methods wherever in the EJBs and a rollback would rollback ALL operations performed by the thread.
[Message sent by forum member 'bhar99328' (bhar99328)]

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