![](/img/trans.png)
[英]Java / EJB 3.0 CMT / JTA / MySQL / Hibernate - Transaction not rolling back
[英]EJB transaction not rolling back
我有上面的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调用都将封装在一个事务中,并且如果发生异常,则将回滚与DB层的整个交互。
我怎样才能做到这一点? 如果我的第二次保存抛出错误,我希望回退第一次保存操作。
谢谢
我使用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>
如果您偶然使用的是JBoss,则很有可能datasoruce错误地定义为不使用JTA事务。 检查是否在JBoss配置中设置了<datasource jta="true" ..
有关更多详细信息,请检查事务不回滚
您没有提到save()方法是如何定义的。 如果使用的是BMP,则无法加入来自CMP的交易,例如atender()。
如果没有,请尝试以下操作:
在atender(Long chamadoId)上方,添加注释@TransactionAttribute(TransactionAttributeType.REQUIRED)。 然后在save()方法的定义上,将此注释@TransactionAttribute(TransactionAttributeType.MANDATORY)
希望有帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.