2 Replies Latest reply on Nov 9, 2013 10:58 AM by qtm

    XA transaction is not rolled back when using several ears deployed in the same server

    qtm

      Hello,

       

      Some time ago I've opened : EJB Transactions over multiple applications in the same JVM to see if in theory I could use XA transactions over several applications deployed in the same server. Now I'm trying to write a test to verify that:

       

      I have 2 ears: EJB1EAR.ear and EJB2EAR.ear deployed under the same server(Jboss 7.2.0 ).

       

      Their content:

       

      EJB1EAR.ear : META-INF - jboss-deployment-structure.xml, MANIFEST.MF

       

                             EJB1.jar - META-INF - ejb-jar.xml, persistence.xml, MANIFEST.MF

       

                                           - Entity1 and BeanImpl1

       

                             EJB1Client.jar - META-INF - MANIFEST.MF

       

                                           - Bean1

       

      EJB2EAR.ear : META-INF - jboss-deployment-structure.xml, MANIFEST.MF

       

                             EJB2.jar - META-INF - ejb-jar.xml, persistence.xml, MANIFEST.MF

       

                                           - Entity2 and BeanImpl2 and StartIt

       

                             EJB2Client.jar - META-INF - MANIFEST.MF

       

                                           - Bean2

       

                             lib  - EJB1Client.jar

       

      the jboss-deployment-structure.xml is the same for both ears:

       

      <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">

       

        <deployment>

       

          <dependencies>

       

            <module name="org.jboss.as.naming" export="true"/>

       

          </dependencies>

       

        </deployment>

       

      </jboss-deployment-structure>

       

      Bean1 :

       

      @Remote

       

      public interface Bean1 {

       

          void test1();

       

      }

       

      BeanImpl1:

       

      @Stateless

       

      public class BeanImpl1 implements Bean1 {

       

          @PersistenceContext(unitName = "firstPU")

       

          private EntityManager em;

       

          @TransactionAttribute(TransactionAttributeType.MANDATORY)

       

          public void test1() {

       

              Entity1 e1 = new Entity1();

       

              e1.setName("TBN");

       

              em.persist(e1);

       

          }

       

      }

       

      persistence.xml: (for EAR1)

       

      <?xml version="1.0" encoding="UTF-8"?>

       

      <persistence version="2.0"

       

          xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       

          xsi:schemaLocation="

       

              http://java.sun.com/xml/ns/persistence

       

              http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

       

          <persistence-unit name="firstPU" transaction-type="JTA">

       

              <jta-data-source>java:jboss/datasources/firstDS</jta-data-source>

       

              <properties>

       

                  <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />

       

                  <property name="hibernate.hbm2ddl.auto" value="validate" />

       

                  <property name="hibernate.show_sql" value="true" />

       

              </properties>

       

          </persistence-unit>

       

      </persistence>

       

      Bean2:

       

      @Local

       

      public interface Bean2 {

       

          void test2();

       

      }

       

      BeanImpl2

       

      @Stateless

       

      public class BeanImpl2 implements Bean2 {

       

          @EJB(lookup = "java:global/EJB1EAR/EJB1/BeanImpl1!ejb1.Bean1")

       

          private Bean1 t1;

       

       

       

          @PersistenceContext(unitName="secondPU")

       

          private EntityManager em;

       

       

       

          @Override

       

          @TransactionAttribute(TransactionAttributeType.REQUIRED)

       

          public void test2() {

       

              t1.test1();

       

              Entity2 e2 = new Entity2();

       

              e2.setTitle("title");

       

              em.persist(e2);

       

              throw new RuntimeException("exception");

       

          }

       

      }

       

      StartIt:

       

      @Singleton

       

      @Startup

       

      public class StartIt { 

       

       

       

          @EJB

       

          private Bean2 t2;

       

          @PostConstruct

       

          @TransactionAttribute(TransactionAttributeType.NEVER)

       

          public void theTest(){

       

              t2.test2();

       

          }

       

      }

       

      persistence.xml: (for EAR2)

       

      <?xml version="1.0" encoding="UTF-8"?>

       

      <persistence version="2.0"

       

          xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       

          xsi:schemaLocation="

       

              http://java.sun.com/xml/ns/persistence

       

              http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

       

          <persistence-unit name="firstPU" transaction-type="JTA">

       

              <jta-data-source>java:jboss/datasources/secondDS</jta-data-source>

       

              <properties>

       

                  <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />

       

                  <property name="hibernate.hbm2ddl.auto" value="validate" />

       

                  <property name="hibernate.show_sql" value="true" />

       

              </properties>

       

          </persistence-unit>

       

      </persistence>

       

      The entities are very simple and the db are already there.

       

      <xa-datasource jta="true" jndi-name="java:jboss/datasources/firstDS" pool-name="TestDS1" enabled="true" use-java-context="true" use-ccm="false">

       

                      <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>

       

                          <xa-datasource-property name="URL">

       

                              jdbc:mysql://localhost:3306/test1

       

                          </xa-datasource-property>

       

                          <driver>mysql</driver>

       

                          <xa-pool>

       

                              <min-pool-size>10</min-pool-size>

       

                              <max-pool-size>20</max-pool-size>

       

                              <prefill>true</prefill>

       

                              <use-strict-min>false</use-strict-min>

       

                              <flush-strategy>FailingConnectionOnly</flush-strategy>

       

                          </xa-pool>

       

                          <security>

       

                              <user-name>test</user-name>

       

                              <password>test</password>

       

                          </security>

       

                      </xa-datasource>

       

                      <xa-datasource jta="true" jndi-name="java:jboss/datasources/secondDS" pool-name="TestDS2" enabled="true" use-java-context="true" use-ccm="false">

       

                  <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>

       

                          <xa-datasource-property name="URL">

       

                              jdbc:mysql://localhost:3306/test2

       

                          </xa-datasource-property>

       

                          <driver>mysql</driver>

       

                          <xa-pool>

       

                              <min-pool-size>10</min-pool-size>

       

                              <max-pool-size>20</max-pool-size>

       

                              <prefill>true</prefill>

       

                              <use-strict-min>false</use-strict-min>

       

                              <flush-strategy>FailingConnectionOnly</flush-strategy>

       

                          </xa-pool>

       

                          <security>

       

                              <user-name>test</user-name>

       

                              <password>test</password>

       

                          </security>

       

                      </xa-datasource>

       

                     <driver name="mysql" module="com.mysql.jdbc">

       

                           <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>

       

                      </driver>

       

                   The module has the 5.1.18 mysql connector version.

       

      My problem is that BeanImpl1 always commits and Entity1 is inserted in the db. I've tried to set the transactionattribute on BeanImpl2 to NOT_SUPPORTED and BeanImpl1 complains that it doesn't have an active transaction, so it is using the transaction started in BeanImpl2. Somehow, it commits at the end of the method test1. I've set the arjuna log level to debug, but I don't see any activity at all regarding my beans. It initializes at server startup, but it doesn't seem to participate in my applications.

       

      I don't know what's wrong.. my understanding of XA, the mysql configuration or smth else. Any help would be appreciated.

       

      thank you