2011-02-03 6 views
0

3.0 스펙에 따라 비 상태 유지 세션 EJB가 있습니다. 1 테이블 업데이트가 성공하고 두번째 테이블 업데이트가 예외를 제공하는 경우상태 비 저장 세션 EJB 3.0의 트랜잭션 롤백

/*Remote Interface*/ 

package com.nseit.ncfm2.data.ejb; 
import java.sql.SQLException; 
import java.util.Collection; 

import javax.ejb.Remote; 
import javax.ejb.TransactionAttribute; 
import javax.ejb.TransactionAttributeType; 
import javax.naming.NamingException; 

import com.nseit.ncfm2.security.Audit; 

@Remote 
public interface ProductionDataChangesRequestsRemote { 

    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public boolean shiftCandidateDetails(String sourceNcfmId, 
      String destinationNcfmId, Collection<String> specialCasesList, String shiftingRemarks, String user, Audit updtAudit) throws NamingException, SQLException; 
} 


/*Bean Class*/ 

package com.nseit.ncfm2.data.ejb; 

import javax.ejb.Remote; 
import javax.ejb.Stateless; 
import javax.ejb.TransactionAttribute; 
import javax.ejb.TransactionAttributeType; 
import javax.ejb.TransactionManagement; 
import javax.ejb.TransactionManagementType; 
import javax.naming.NamingException; 

import com.nseit.ncfm2.security.Audit; 
import com.nseit.ncfm2.util.server.lookup.LookUpServerResources; 
import java.sql.*; 
import java.util.*; 

/** 
* Session Bean implementation class ProductionDataChangesRequestsBean 
*/ 
@Stateless(name = "ProductionDataChangesRequestsBean", mappedName = "ProductionDataChangesRequestsEJB") 
@Remote(ProductionDataChangesRequestsRemote.class) 
@TransactionManagement(TransactionManagementType.CONTAINER) 
public class ProductionDataChangesRequestsBean implements 
     ProductionDataChangesRequestsRemote { 

/** 
* Default constructor. 
*/ 
public ProductionDataChangesRequestsBean() { 
    // TODO Auto-generated constructor stub 
} 

@Override 
@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public boolean shiftCandidateDetails(String sourceNcfmId, 
     String destinationNcfmId, Collection<String> specialCasesList, 
     String shiftingRemarks, String user, Audit updtAudit) 
     throws NamingException, SQLException { 
    // TODO Auto-generated method stub 
    Connection conn = null; 
    PreparedStatement pstmt = null; 

    int updtCnt = 0; 

    boolean areDetailsShifted = false; 

    try { 
     .............. 
     .............. 
     .............. 

     /* Start: update table-1 */ 
     .............. 
     .............. 
     .............. 

     updtCnt = pstmt.executeUpdate(); 
     .............. 
     .............. 
     .............. 

     /* End: update table-1 */ 


     /* Start: update table-2 */ 
     .............. 
     .............. 
     .............. 

     updtCnt = pstmt.executeUpdate(); 
     .............. 
     .............. 
     .............. 

     /* End: update table-2 */ 

     areDetailsShifted = true; 

    } /*catch (SQLException e) { 
     // TODO Auto-generated catch block 
     System.out 
       .println("SQLException in ProductionDataChangesRequestsBean.shiftCandidateDetails(...) " 
         + e.getMessage()); 
     // e.printStackTrace(); 

     context.setRollbackOnly(); 

    } */finally { 
     LookUpServerResources.closeStatement(pstmt); 
     LookUpServerResources.closeConnection(conn); 
    } 

    return areDetailsShifted; 
} 

} 

현재, 롤백이 진행되지 않으며, 1 테이블 즉 레코드가 업데이트됩니다.

SQLException이 발생하는 경우 (또는 런타임 예외가 발생하는 경우) 트랜잭션이 롤백되기를 원합니다.

내가 두 가지 방법 시도 : 예외 : SQLException
  • 이 두 경우에 예외 : SQLException에게
  • 을 던지기위한 catch 블록에서 context.setRollbackOnly()

    1. 사용, 트랜잭션은 롤백하지 않았다. SQLException으로 잡기 후 context.setRollbackOnly()

    를 호출하지 않고

  • (나는 모든 응용 프로그램 예외를 가지고 있지 않는 한) @ApplicationException 주석의 사용없이

    1. :이 달성 할 수있는 방법

      또는 표준 방법은 무엇입니까?

  • 답변

    3

    당신은 당신의 빈에서 JDBC API를 사용하는 것 같습니다 RuntimeException

    +1

    이것은 단지 우리에게 도움이되는 제안 일뿐입니다. 그래서 왜 Downvote? – JSS

    -1

    을 던져해야합니다. 나는 컨테이너가 그 JDBC 트랜잭션을 관리한다고 생각하지 않는다. CMT의 경우 롤백이 예상대로 작동하도록 컨테이너 관리 엔터티 관리자에 대한 작업을 호출해야합니다.

    1

    기본 방법은 JDBC를 사용하는 대신 지속성을 위해 기본 JPA을 사용하는 것입니다. JPA은 EJB 3.x 호환 컨테이너에 잘 통합 된 표준 OR 매핑 솔루션을 제공합니다.

    코드에서 사용자는 TransactionManagementType.CONTAINER이지만 여전히 수동으로 트랜잭션을 관리하고 있음을 나타냅니다. 빈 관리 트랜잭션 경계에서

    는 세션 또는 메시지 구동 Bean의 코드가 명시 적으로 는 트랜잭션의 경계를 표시합니다. 컨테이너 관리 트랜잭션을 사용하는 콩은 코딩이 덜한 이 필요하지만 한 가지 제한이 있습니다. 메소드가 실행 중일 때 은 단일 트랜잭션과 연관되거나 전혀 트랜잭션과 관련 될 수 없습니다. 이 제한 사항으로 인해 빈을 코딩하기가 어려우면 빈 관리 트랜잭션 사용을 고려해야합니다.

    +0

    @downvoter -1에 대한 설명 –