2014-11-10 5 views
0

나는 위의 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) 저장, 저장; 하나의 Exception (Runtime 또는 Not Both) 첫 번째 저장이 롤백되지 않는 이유를 이해할 수 없습니다. 나를 위해, 모든 EJB 호출은 하나의 트랜잭션에서 캡슐화 될 것이며 예외가 발생하면 DB 계층과의 전체 상호 작용이 롤백됩니다.

이 동작을 어떻게 수행합니까? 두 번째 저장에서 오류가 발생하면 첫 번째 저장 작업을 롤백해야합니다. 내가 DBMS 및 Application Server와 제이보스 8.1로 MySQL을 사용하고

감사


. 기본값을 변경하지 않았으므로 자동 커밋 모드가 활성화되어 있다고 생각하지 않습니다.

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

롤백해야합니다. 어떤 DBMS를 사용하고 있습니까? 그리고 지속성 장치는 어떻게 구성되어 있습니까? 실패해야만하는 유일한 이유는 활성화 된 자동 커밋 모드가있는 경우입니다. – Gimby

+0

우연히 배포 디스크립터가 있습니까? 설명자의 저장 메서드에 대해 TransactionAttribute를 재정의 할 수 있습니까? – jjd

답변

1

도움

희망을 놓지로 JTA 트랜잭션을 사용하십시오. JBoss config에 <datasource jta="true" ..이 설정되어 있는지 확인하십시오. 자세한 내용을 보려면 Transactions don't rollback

+0

안녕 가스, 고마워요! 사실입니다. standalone.xml에 데이터 소스의 정의를 추가했으며 jta = "true"속성이 없습니다. 나는 그것과 함께 지금 시험해 볼 것이다. –

0

내 데이터 소스 구성 방법을 정의 하였다() 당신은 저장하는 방법을 언급하지 않았다이다. BMP를 사용하는 경우 atender()와 같은 CMP의 트랜잭션에 참여할 수 없습니다.

하지 않으면,이 시도 : atender (긴 chamadoId) 이상

은 주석 @TransactionAttribute (TransactionAttributeType.REQUIRED)를 넣습니다. 그리고 저장() 메서드의 정의를 통해이 주석 @TransactionAttribute (TransactionAttributeType.MANDATORY) 우연은 JBoss를 사용하는 경우 그 datasoruce 잘못 정의되어 높은 확률이

+0

답장을 보내 주셔서 감사합니다. 제가 생각하기에, 질문에서 조금 내려 봤습니다. –

+0

죄송합니다. 슬라이드 바를 보지 못했습니다. 그러나 두 번째 제안을 시도해 볼 수 있습니다. 필자는 REQUIRED 속성 유형이 항상 존재한다면 트랜잭션에 참여하도록 변환되지 않으며 REQUIRES_NEW 속성이 정의 된 것처럼 새로운 트랜잭션을 생성한다는 것을 읽었습니다. 솔직히, 나는 이것을 어디서 발견했는지 기억할 수는 없지만 나는 너에게 비슷한 문제가있다. 그러나 이전 회신의 두 번째 부분을 사용하려고하면 save() 메서드가 새 트랜잭션을 시작하고 호출자의 트랜잭션에 참가하지 않도록해야합니다. 또한 시도하십시오 –