简体   繁体   English

EJB事务不回滚

[英]EJB transaction not rolling back

I've the above 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);
        }
    }

}

If my second save, save(chamado); 如果是第二次保存,请保存(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. 对我来说,每个EJB调用都将封装在一个事务中,并且如果发生异常,则将回滚与DB层的整个交互。

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. 我使用MySQL作为DBMS,使用Wildfly 8.1作为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 这是我在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>

If you by chance are using JBoss there is high probability that datasoruce is incorrectly define not to use JTA transactions. 如果您偶然使用的是JBoss,则很有可能datasoruce错误地定义为不使用JTA事务。 Check if you have <datasource jta="true" .. set in JBoss config. 检查是否在JBoss配置中设置了<datasource jta="true" .. For more details check Transactions don't rollback 有关更多详细信息,请检查事务不回滚

You didn't mention how save() method was defined. 您没有提到save()方法是如何定义的。 If it's using BMP then it can't join transactions from CMP such as atender(). 如果使用的是BMP,则无法加入来自CMP的交易,例如atender()。

If not, then try this: 如果没有,请尝试以下操作:

Over atender(Long chamadoId) put the annotation @TransactionAttribute(TransactionAttributeType.REQUIRED). 在atender(Long chamadoId)上方,添加注释@TransactionAttribute(TransactionAttributeType.REQUIRED)。 And over the the definition of the save() method put this annotation @TransactionAttribute(TransactionAttributeType.MANDATORY) 然后在save()方法的定义上,将此注释@TransactionAttribute(TransactionAttributeType.MANDATORY)

hope that help 希望有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM