EJB事务没有回滚

时间:2014-11-10 12:08:34

标签: java transactions ejb

我是上面的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);
        }
    }

}

如果我的第二次保存,保存(chamado);抛出一个异常(运行时或不运行)第一个保存没有回滚,我不明白为什么。 对我来说,每个EJB调用都将封装在一个事务中,如果发生异常,则将回滚与数据库层的整个交互。

我该如何完成此行为?如果我的第二个保存引发错误,我希望回滚第一个保存操作。

谢谢


我使用MySQL作为DBMS,使用Wildfly 8.1作为Application Server。 我没有改变任何默认值,所以我不认为启用自动提交模式。

<?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>

这是我在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>

2 个答案:

答案 0 :(得分:1)

如果你偶然使用JBoss,那么很有可能数据定义被错误地定义为不使用JTA事务。检查您是否在JBoss配置中设置了<datasource jta="true" ..。有关详细信息,请查看Transactions don't rollback

答案 1 :(得分:0)

您没有提到如何定义save()方法。如果它使用BMP,则它无法加入CMP中的事务,例如atender()。

如果没有,那就试试这个:

Over atender(Long chamadoId)放置注释@TransactionAttribute(TransactionAttributeType.REQUIRED)。并且在save()方法的定义中放置了这个注释@TransactionAttribute(TransactionAttributeType.MANDATORY)

希望得到帮助