XA transaction is not rolled back when using several ears deployed in the same server
qtm Nov 8, 2013 2:10 AMHello,
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