2016-11-15 8 views
1

EJB 트랜잭션 관리를 이해하려고합니다. 나는 아래의 코드를 작성하고 내 server.xml에이EJB 트랜잭션 관리

<dataSource jndiName="jdbc/mydb" transactional="false"> 
.... 
</dataSource> 

내가 수동으로 기본 키 제약 조건이있는 테이블에 레코드를 삽입 아래 같이 보입니다

@Stateless 
@TransactionManagement(TransactionManagementType.BEAN) 
public class BookRepositoryBean { 

    @Resource(lookup = "jdbc/mydb") 
    private DataSource dataSource; 

    public void create(List<Book> books) { 

    try { 
    for(Book book: books) { 
     Connection con = dataSource.getConnection(); 
     PreparedStatement stmt = con.preparedStatement("insert into ...."); 
     stmt.setString(1, ...); 
     stmt.executeUpdate(); 
    } 
    } catch(SQLException e) { 
    throw new RuntimeException(e.getMessage()); 
    } 
} 

스피어의 자유에 배치 한 후 실행 시도 내 코드는 하나가 중복 레코드이고 다른 하나가 새로운 레코드 인 두 레코드를 유지합니다.

내가 다른 옵션을 시도하고 다음

  1. 서버 XML 데이터 소스 관찰 : = 트랜잭션 거짓
    TransactionManagementType = BEAN
    결과 : 1/2 기록은 지속되었다. 트랜잭션 관리 코드가 작성되었으므로 이는 예상됩니다.

  2. 서버 XML 데이터 소스 : = 트랜잭션 사실
    TransactionManagementType = 컨테이너
    결과 : 0/2 기록이 지속되었다. 트랜잭션 관리가 활성화되어 있으므로 레코드가 0 개 삽입됩니다.

  3. 서버 XML 데이터 소스 : 거짓 = 트랜잭션
    TransactionManagementType = 컨테이너
    결과 : 트랜잭션 = 사실
    TransactionManagementType = BEAN
    결과 : 1/2 1/2 기록

  4. 서버 XML 데이터 소스를 지속 기록이 지속되었습니다. 코드 레벨에서 트랜잭션 관리를 해제 했으므로 1 레코드가 지속되었음을 이해했습니다.

  5. 서버 XML 데이터 소스 :
    = 트랜잭션 진정한 제거 @Stateless 및
    결과 @TransactionManagement 주석 : 0/2 기록이 지속되었다.

3 인 경우 1 레코드가 삽입 된 이유를 알 수 없습니다. 컨테이너 수준의 트랜잭션 관리는 코드에서 사용 가능할 때만 작동하고 컨테이너 수준에서 작동 가능할 때만 작동한다고 가정합니다. 내가 맞습니까?

5 경우에는 클래스가 EJB가 아닌 경우 0 레코드가 유지 된 이유를 알 수 없습니다. 나는 항상 트랜잭션 관리가 EJB에서만 사용 가능하다고 가정했다. 이 테스트는 나를 틀린 것으로 판명했다. 이제 일반 Java 클래스보다 EJB를 선택해야하는 이유를 알지 못합니다.

누구든지 설명해 주실 수 있습니까?

답변

2

# 5와 관련하여 주석을 제거하고 일반 Java 클래스 인 경우 호출자의 트랜잭션 및 컨텍스트에서 실행됩니다. 컨테이너를 관리하는 다른 EJB를 호출하는 사람이 트랜잭션입니까?

+0

예 invoker는 EJB입니다. 가리키는 주셔서 감사합니다. 호출자에 대한 Stateless 주석을 제거하여 다시 테스트하려고 시도합니다. –

+0

발신자에게 Stateless 주석을 제거하고 테스트했습니다. 1/2 레코드가 지속됩니다. 문제를 지적 해 주셔서 감사합니다. –

1
  • 서버 XML 데이터 소스
      : 트랜잭션 = 거짓
      TransactionManagementType을 = 컨테이너
      결과 : 1/2 기록을 이해하는 경우 3, 내가 해달라고에서

      을 지속하는 이유 1 개 기록 삽입됩니다.컨테이너 수준의 트랜잭션 관리는 코드에서 사용 가능할 때만 작동하고 컨테이너 수준에서 작동 가능할 때만 작동한다고 가정합니다. 내가 맞습니까?
  • 용기이 EJB의 트랜잭션 관리, 리소스가 트랜잭션에 참가할 수없는 경우 (즉, 오류가 트랜잭션 =) 각각의 동작을 개별적으로 실행 비록. 중복 키 삽입 실패하고 다른 키 삽입 성공했습니다.

    +0

    따라서 제 5의 경우 jboss 나 LTE가없는 다른 응용 프로그램 서버에서 동일한 코드를 실행하면 레코드가 유지됩니까? –

    +0

    케이스 # 5가 잘못 판명되었습니다. 이것은 LTC가 작동하는 방식이 아니므로 제 답변에서 그 부분을 제거했습니다. –