1

I am running Glassfish 3.1.1 with an Oracle database and have run into an issue with transactions not rolling back, but only on one specific environment so far. The same application works as expected on other machines. However, two separate Glassfish domains on the same machine are impacted.

Within the affected environment, I have similar results with both a container-managed transactions (CMT) inside an EJB that throws a RuntimeException, and a bean-managed transaction (BMT) with UserTransaction#rollback().

In both cases, the underlying issue appears to be that the JDBC connection is somehow still set with autoCommit = true even though there is a JTA transaction in progress.

My EJB/CMT test looks like this:

@Named
@Stateless
public class TransactionTest { 

  @PersistenceContext
  EntityManager entityManager;

  @TransactionAttribute(TransactionAttributeType.REQUIRED)
  public void rollbackTest() {
    Foo foo = new Foo();
    entityManager.persist(foo);
    entityManager.flush();

    throw new RuntimeException("should be rolled back");
  }
}

and my BMT/UserTransaction test is like this:

public void rollbackUtxTest() throws Exception {
    utx.begin();

    Foo foo = new Foo();
    entityManager.persist(foo);
    entityManager.flush();

    utx.rollback();   
}

When I call either method, the INSERT INTO FOO is committed, even though the transactions were rolled back.

What am I missing - perhaps I don't have my connection pool / datasource is not set up right?

I'm using OracleConnectionPoolDataSource as the datasource class name. Is there something I need to do to ensure my database connections participate in JTA transactions?

UPDATE 1 I originally thought this was an issue with OracleConnectionPoolDataSource but it turned out it was not correlated. The same exact pool configuration works on one environment but not the other.

UPDATE 2 Clarified that this is not specifically an EJB/CMT issue, but a general JTA issue.

UPDATE 3 added info about JDBC autocommit. Confirmed that persistence.xml is correct.

Roman C
  • 49,761
  • 33
  • 66
  • 176
wrschneider
  • 17,913
  • 16
  • 96
  • 176

2 Answers2

3

It looks like this may be an issue with domain.xml, possibly a Glassfish bug.

In persistence.xml, I have

<jta-data-source>jdbc/TEST</jta-data-source>.

In domain.xml, I have

<jdbc-resource pool-name="TEST_POOL" description="" jndi-name="jdbc/TEST"></jdbc-resource>

But no corresponding <resource-ref ref="jdbc/TEST"> - either missing or misspelled. (I believe I ended up in that state by creating the JNDI datasource through the UI, realizing the name is wrong, then fixing the JNDI name in domain.xml jdbc-resource by hand but not fixing it in resource-ref.

In this case, my injected EntityManager still works but is not participating in JTA transactions. If I fix domain.xml, it works as expected.

wrschneider
  • 17,913
  • 16
  • 96
  • 176
  • Same happened to me. Its mind-boggling that the server starts up, i see no difference in the GUI and transactions are just set to auto-commit mode -.- Thanks so much for raising this issue, would have taken me forever to find otherwise^^ – icyerasor Nov 09 '15 at 16:11
  • 1
    Glad someone found this helpful. Disturbing that the issue is still open and not fixed in Glassfish 4.0 either. – wrschneider Nov 09 '15 at 16:13
  • I had this exact problem in an embedded GlassFish container and have been searching high and low for a solution. Turns out my test-domain.xml was missing the element. Thanks! – Matt May 18 '16 at 06:07
0

You didn't wrap your Exception in an EJBException.

See http://docs.oracle.com/javaee/6/tutorial/doc/bnbpj.html