Java EJB事务未回滚
我已经完成了上述EJB:Java EJB事务未回滚,java,transactions,ejb,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; }
@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);
}
}
}
@无状态
公共类ItilEJB{
@持久上下文
受保护的实体管理器em;
公共找不到(类clazz,长id){
if(clazz==null | | id==null){
返回null;
}
返回em.find(clazz,id);
}
公共Chamado atender(长chamadoId){
Chamado Chamado=find(Chamado.class,chamadoId);
如果(!isChamadoAtendido(chamadoId)){
状态emAndamento=新状态(Status.EM_ANDAMENTO);
HistoricoChamado historico=新的HistoricoChamado();
historico.Setdescripao(“Início do atendemento do chamado.”);
塞查马多历史博物馆(查马多);
塞斯塔图斯历史公司(伊曼达曼托);
historico.setSla(chamado.getSla());
查马多·塞斯塔图斯(伊曼达曼托);
拯救(历史公司);
拯救(查马多);
}
返回查马多;
}
公共作废保存(基本实体){
if(entity.getId()==null){
如果(!helper.canInsert(此,实体)){
抛出新的AlertMessageRuntimeException(“user.db.constraint”);
}
em.persist(实体);
}否则{
如果(!helper.canUpdate(此,实体)){
抛出新的AlertMessageRuntimeException(“user.db.constraint”);
}
合并(实体);
}
}
}
如果我第二次保存,保存(chamado);抛出一个异常(无论运行时与否)第一次保存未回滚,我不明白为什么。
对我来说,每个EJB调用都将封装在一个事务中,如果发生异常,与DB层的整个交互都将回滚
我怎样才能完成这个行为?如果第二次保存引发错误,我希望回滚第一次保存操作
谢谢
我使用MySQL作为DBMS,使用Wildfly 8.1作为应用服务器。 我没有更改任何默认设置,因此我认为自动提交模式不是启用的
<?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>
org.hibernate.ejb.HibernatePersistence
java:jboss/datasources/MySQLDS
这是我在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>
jdbc:mysql://${env.OPENSHIFT\u mysql\u DB\u HOST}:${env.OPENSHIFT\u mysql\u DB\u PORT}/${env.OPENSHIFT\u APP\u NAME}
mysql
${env.OPENSHIFT\u MYSQL\u DB\u USERNAME}
${env.OPENSHIFT\u MYSQL\u DB\u PASSWORD}
选择1
真的
60000
空闲连接
您没有提到save()方法是如何定义的。如果它使用BMP,则无法从CMP加入事务,例如atender()
如果没有,请尝试以下方法:
在atender(Long chamadoId)上放置注释@TransactionAttribute(TransactionAttributeType.REQUIRED)。在save()方法的定义上,将这个注释放在@TransactionaAttribute(TransactionaAttribute.employment)上
希望您能提供帮助如果您碰巧正在使用JBoss,则datasoruce很可能错误地定义不使用JTA事务。检查是否有
应该回滚。您使用的是哪种数据库管理系统?持久化单元是如何配置的?它应该失败的唯一原因是如果有某种自动提交模式被激活。你有部署描述符吗?您是否可以在描述符中覆盖save方法的TransactionAttribute?谢谢您的回复!我想我已经,把问题看得有点低了。对不起,我没有注意到滑动条。不过,你可以试试我的第二个建议。我已经读到,如果事务存在,所需的属性类型并不总是转换为加入事务,有时它会创建一个新事务,就好像定义了REQUIRES\u新属性一样。老实说,我不记得我在哪里找到这个,但我有一个类似的问题,你的;但是,尝试使用我上一个回复的第二部分,它应该强制save()方法不启动新事务并加入调用者的事务。还有,tryHi Gas,谢谢!这是真的,我在standalone.xml中添加了数据源的定义,但它没有jta=“true”属性。我现在就试试这个。