Cristiano Passos
Cristiano Passos

Reputation: 51

EJB transaction not rolling back

I've the above EJB:

    @Stateless
public class ItilEJB  {
    @PersistenceContext
    protected EntityManager em;

    public <T> T find(Class<T> clazz, Long id) {
        if (clazz == null || id == null) {
            return null;
        }

        return em.find(clazz, id);
    }


public Chamado atender(Long chamadoId) {

        Chamado chamado = find(Chamado.class, chamadoId);

        if (!isChamadoAtendido(chamadoId)) {
            Status emAndamento = new Status(Status.EM_ANDAMENTO);

            HistoricoChamado historico = new HistoricoChamado();
            historico.setDescricao("Início do atendimento do chamado.");
            historico.setChamado(chamado);
            historico.setStatus(emAndamento);
            historico.setSla(chamado.getSla());

            chamado.setStatus(emAndamento);

            save(historico);

            save(chamado);
        }

        return chamado;
    }

public void save(BaseEntity entity) {

        if (entity.getId() == null) {
            if (!helper.canInsert(this, entity)) {
                throw new AlertMessageRuntimeException("user.db.constraint");
            }
            em.persist(entity);
        } else {
            if (!helper.canUpdate(this, entity)) {
                throw new AlertMessageRuntimeException("user.db.constraint");
            }
            em.merge(entity);
        }
    }

}

If my second save, save(chamado); throws one Exception (Both runtime or not) the first save is not rolled back, I can't understand why. For me, every EJB call would be encapsulate in one transaction and if a Exception occurs, the whole interaction with the DB layer would be rolled back.

How can I accomplish this behavior? If my second save throws a error, I want the first save action be rolled back.

Thanks


I'm using MySQL as DBMS and Wildfly 8.1 as Application Server. I haven't changed any of the defaults, so I don't think that auto-commit mode is enable.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="primary">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:jboss/datasources/MySQLDS</jta-data-source>

        <properties>
            <property name="hibernate.show_sql" value="true" />
        </properties>
    </persistence-unit>
</persistence>

This is my datasource configuration in standalone.xml

<datasource jndi-name="java:jboss/datasources/MySQLDS" enabled="${mysql.enabled}" use-java-context="true" pool-name="MySQLDS" use-ccm="true">
                    <connection-url>jdbc:mysql://${env.OPENSHIFT_MYSQL_DB_HOST}:${env.OPENSHIFT_MYSQL_DB_PORT}/${env.OPENSHIFT_APP_NAME}</connection-url>
                    <driver>mysql</driver>
                    <security>
                      <user-name>${env.OPENSHIFT_MYSQL_DB_USERNAME}</user-name>
                      <password>${env.OPENSHIFT_MYSQL_DB_PASSWORD}</password>
                    </security>
                    <validation>
                        <check-valid-connection-sql>SELECT 1</check-valid-connection-sql>
                        <background-validation>true</background-validation>
                        <background-validation-millis>60000</background-validation-millis>
                        <!--<validate-on-match>true</validate-on-match>-->
                    </validation>
                    <pool>
                        <flush-strategy>IdleConnections</flush-strategy>
                    </pool>
                </datasource>

Upvotes: 0

Views: 1724

Answers (2)

Gas
Gas

Reputation: 18020

If you by chance are using JBoss there is high probability that datasoruce is incorrectly define not to use JTA transactions. Check if you have <datasource jta="true" .. set in JBoss config. For more details check Transactions don't rollback

Upvotes: 2

user2770375
user2770375

Reputation:

You didn't mention how save() method was defined. If it's using BMP then it can't join transactions from CMP such as atender().

If not, then try this:

Over atender(Long chamadoId) put the annotation @TransactionAttribute(TransactionAttributeType.REQUIRED). And over the the definition of the save() method put this annotation @TransactionAttribute(TransactionAttributeType.MANDATORY)

hope that help

Upvotes: 0

Related Questions