Concurrency Utilities for Java EE
Concurrency Utilities for Java™ EE는 병렬로 실행되는 태스크를 제출하거나 스케줄하고, Java EE 컨텍스트를 상속하는 스레드를 작성하며 비동기 콜백과 같은 인터페이스를 시작하기 위해 Java EE 컨텍스트를 전송하도록 해주는 비동기 프로그래밍 모델입니다.
Concurrency Utilities for Java EE는 Java EE 프로그램이 조작을 병렬 태스크로 분해하도록 하여 성능을 향상시킬 수 있습니다.
- 보안 컨텍스트
- 글로벌 컨텍스트
- 작업 영역 컨텍스트
동시성 인터페이스
Concurrency Utilities for Java EE는 4개의 자원 기본 유형을 제공하며 이들 각각은 JNDI에서 구성 가능하고 사용할 수 있습니다.
- 관리 대상 실행기 서비스
- 애플리케이션은 관리 대상 실행기를 사용하여 스레드로 실행을 시작할 수 있는 비동기 태스크를 제출하며 해당 스레드는 자원이 이를 실행할 수 있을 때 일반적으로 풀에서 시작됩니다. 태스크는 Callable 또는 Runnable의 인스턴스입니다. 애플리케이션에게는 상태를 확인하고 태스크 완료 결과를 확보하거나 대기할 수 있는 Future가 지정됩니다. 관리 대상 실행기에는 태스크 그룹 또는 그룹 내 태스크 하나의 완료를 제출하고 대기하는 인터페이스가 포함됩니다. 태스크는 태스크를 제출하는 스레드 컨텍스트를 상속합니다.
- 관리 대상 스케줄된 실행기 서비스
- 애플리케이션은 관리 대상 스케줄된 실행기를 사용하여 특정 시점 이후에 실행을 시작하도록 비동기 태스크를 스케줄합니다. 태스크는 Callable 또는 Runnable의 인스턴스입니다. 관리 대상 스케줄된 실행기에는 사용자 정의 비즈니스 로직에 따라 고정 간격 또는 계산된 간격으로 태스크의 자동 재스케줄을 위한 인터페이스가 포함됩니다. 태스크는 태스크를 스케줄하는 스레드 컨텍스트를 상속합니다.
- 관리 스레드 팩토리
- 애플리케이션은 관리 스레드 팩토리를 사용하여 관리 스레드 팩토리를 검색 또는 인젝션한 애플리케이션 컴포넌트의 컨텍스트를 상속하는 새 스레드를 구성합니다.
- 컨텍스트 서비스
- 애플리케이션은 컨텍스트 서비스를 사용하여 컨텍스트 프록시를 구성하며 이를 통해 프록시를 작성한 스레드 컨텍스트를 상속하기 위해 하나 이상의 프록시 인터페이스 호출을 허용합니다.
트랜잭션
제출 또는 스케줄된 모든 태스크, 관리 스레드 팩토리 스레드, 컨텍스트 프록시 조작은 일반적인 엔터프라이즈 Bean의 컨테이너 관리 트랜잭션과 같이 이전에 일시중단된 스레드에 있던 임의 트랜잭션으로 호출됩니다. 이는 EJB(Enterprise JavaBeans) 메소드가 TX_NOT_SUPPORTED로 호출되는 경우와 유사합니다. 런타임은 메소드 호출 전에 로컬 트랜잭션 포함을 시작합니다. 태스크는 이 트랜잭션이 호출 Java EE 컴포넌트에 가능한 경우 자체 글로벌 트랜잭션을 시작할 수 있습니다. 컨텍스트 프록시에 대한 이 동작은 TRANSACTION 실행 특성을 USE_TRANSACTION_OF_EXECUTION_THREAD 값으로 지정하여 대체할 수 있습니다. 특성을 사용하여 트랜잭션은 실행 스레드에 계속 남아 있기 때문에 프록시 메소드 내에서 수행되는 트랜잭션 조작은 호출 스레드 트랜잭션으로 커미트하고 롤백할 수 있습니다.
예를 들어, 태스크 내에서 엔티티 Bean을 호출하는 경우, 현재 스레드에서 사용할 수 있는 글로벌 트랜잭션 컨텍스트가 있어야 합니다. 태스크가 로컬 트랜잭션 컨텍스트를 시작하기 때문에 TX_REQUIRES 또는 이와 동등하게 표시된 메소드가 포함된 세션 Bean에 모든 엔티티 Bean 로직을 캡슐화할 수 있습니다. 이 프로세스는 하나 이상의 엔티티 Bean 메소드에 액세스할 수 있는 글로벌 트랜잭션 컨텍스트를 설정합니다.
Java EE 컴포넌트 메타데이터에 대한 액세스
태스크가 Java EE 컴포넌트인 경우(예: 세션 Bean) 자체 메타데이터는 메소드가 호출될 때 활성화됩니다. 태스크가 단순 Java 오브젝트인 경우, 작성 컴포넌트의 Java EE 컴포넌트 메타데이터는 Bean에 사용할 수 있습니다. 스레드를 제출하는 것처럼 태스크는 java:comp, java:module, java:app 네임스페이스를 검색할 수 있습니다. 이 검색을 통해 Bean은 다른 Java EE 컴포넌트인 것처럼 데이터 소스, 연결 팩토리, 엔터프라이즈 Bean과 같은 자원에 액세스할 수 있습니다. 작성 컴포넌트의 환경 특성도 태스크에 사용할 수 있습니다.
java:comp 네임스페이스는 작성 컴포넌트에 사용할 수 있는 네임스페이스와 동일하며 같은 제한이 적용됩니다. 예를 들어, 엔터프라이즈 Bean 또는 서블릿에 java:comp/env/ejb/MyEJB EJB 참조가 있는 경우 이 EJB 참조는 태스크에 사용할 수 있습니다.
연결 관리
태스크는 해당 작성 Java EE 컴포넌트가 java:comp 자원 참조를 사용하여 확보한 데이터 소스 및 연결 팩토리를 사용할 수 있습니다. (자원 참조에 대한 자세한 정보는 참조 주제를 참조하십시오.) 그렇지만 Bean 메소드는 get, use, close 패턴을 사용하여 이러한 연결에 액세스해야 합니다. 비동기 태스크의 메소드 호출 사이에서는 연결 캐싱이 없습니다. 연결 팩토리 또는 데이터 소스는 캐시될 수 있지만, 연결에서는 모든 메소드 호출을 검색하고 사용한 다음 닫아야 합니다. 태스크 메소드가 글로벌 JNDI(Java Naming and Directory Interface) 이름을 사용하여 연결 팩토리 및 데이터 소스를 검색하는 동안에는 다음과 같은 이유로 이는 권장되지 않습니다.
- JNDI 이름은 애플리케이션에 하드코딩됩니다(예: 특성 또는 문자열 리터럴로).
- 연결 팩토리는 공유 범위를 지정할 방법이 없기 때문에 공유되지 않습니다.
태스크에서 연결에 액세스하는 올바른 방법과 올바르지 않은 방법 모두를 보여주는 코드 예는 예: 동시성 연결 관리 주제를 참조하십시오.
컨텍스트 태스크의 지연된 시작
Concurrency Utilities for Java EE는 Java EE 스레드 컨텍스트 정보 직렬화를 허용하여 지연된 시작을 지원합니다. 컨텍스트 프록시는 ContextService.createContextualProxy 메소드에 제공된 인스턴스가 직렬화되면 직렬화됩니다. 이 시점에서 컨텍스트 서비스는 WorkManager에서 사용되는 Java EE 컨텍스트 스냅샷을 작성합니다. 그러면 결과로 작성되는 컨텍스트 프록시가 직렬화 가능해지며 데이터베이스 또는 파일로 저장됩니다. 이는 현재 보안 ID 또는 로케일과 같은 Java EE 서비스 컨텍스트를 저장한 후, 나중에 이들 컨텍스트를 확장하고 이 컨텍스트에서 일부 태스크를 실행해야 할 때 유용합니다. 컨텍스트 프록시의 모든 인터페이스 메소드는 이전에 캡처된 스레드 컨텍스트로 실행됩니다.
모든 컨텍스트 프록시는 이를 직렬화한 동일한 애플리케이션이 역직렬화해야 합니다. 모든 EJB 및 클래스는 포함된 오브젝트를 올바르게 확장하려면 Java에 표시되어야 합니다.
지연된 시작 및 보안
보안 서비스 컨텍스트의 경우 CSIv2(Common Secure Interoperability Version 2) ID 어설션이 사용되어야 할 수도 있습니다. ID 어설션은 컨텍스트 프록시가 역직렬화되고 JAAS(Java Authentication and Authorization Service) 주제(Subject) ID 신임 정보 지정에 대해 실행되는 경우에 필요합니다. 컨텍스트 프록시를 사용할 때 ID 어설션을 사용해야 하는 경우 다음 주제를 검토하여 제대로 이해하십시오.
- CSIv2(Common Secure Interoperability Version 2) 및 SAS(Security Authentication Service) 인증 프로토콜 구성
- ID 어설션
제품의 다른 버전에서는 컨텍스트 프록시 상호 운용성에 관련된 제한사항이 있을 수도 있습니다.
JPA 관련 제한사항
JPA 확장 지속성 컨텍스트 내에서 비동기 태스크 사용은 지원되지 않습니다.
JPA 확장 지속성 컨텍스트는 Concurrency Utilities for Java EE의 스케줄링 및 다중 스레드 기능과 일관성이 없으며 비동기 태스크에서 액세스되지 않습니다.
마찬가지로, EntityManager 인스턴스가 스레드에 안전하지 않기 때문에 비동기 태스크는 javax.persistence.EntityManager(또는 서브클래스)를 매개변수로 사용하면 안됩니다.