programing

시스템 충돌 후 Unit Of Work 예외 발생

css3 2023. 10. 17. 20:29

시스템 충돌 후 Unit Of Work 예외 발생

컨텍스트:

애플리케이션이 a에서 개체를 유지합니다.PendingJobTable, 회수해서 처리하는 거죠이 테이블은 처리되기 전에 원래 상태로 개체를 보관합니다.

예약된 작업 중 하나가 실행됨@Startup모든 원래 개체를 검색하여 처리하는 워커를 생성합니다.

@Singleton
@Startup
public class PendingJobExecutor {
    @EJB
    private PendingJobWorker pendingJobWorker;

    @PostConstruct
    public void startUp() {
        Logger.info("Executing pending jobs ...");
        pendingJobWorker.runPendingJobs();
    }
}

PendingJobWorker단순히 주사합니다.PendingService그리고 전화를 합니다.pendingService.executePendingJobs()방법:

@Singleton
public class PendingJobWorker {
    private final PendingService pendingService;

    @Inject
    public PendingJobWorker(
            @Pending final PendingService pendingService) {
        this.pendingService = pendingService;
    }

    public void runPendingJobs() {
        pendingService.executePendingJobs();
    }
}

PendingService보류 중인 모든 작업을 검색합니다.findPendingJobs, 작업자가 하나씩(Future) 처리한 다음 을 사용하여 결과 개체를 저장할 수 있습니다.saveJob:

@Transactional
public abstract class JobRepositoryBase {
    @PersistenceContext(unitName = "Production")
    protected EntityManager entityManager;

    protected PendingJob findPendingJob(final UUID jobId) {
        return entityManager.find(PendingJob.class, jobId);
    }

    protected void saveJob(final UUID jobId, final Future<? extends Job> jobFuture) {
        try {
            // Save processed object
            final var job = jobFuture.get();
            entityManager.persist(job);
            entityManager.flush();

            Logger.info("Processed object {} persisted.", jobId);
        } catch (final InterruptedException | ExecutionException e) {
            Logger.error(e, "Persisting the job with ID {} failed!", jobId);
            Thread.currentThread().interrupt();
        } catch (final CancellationException e) {
            Logger.error(e, "The job with ID {} was cancelled!", jobId);
        }
    }

에 항목을 추가하는 동안PendingJobTable다시 시작한 후 수동(QueryConsole)으로 작동하며, 충돌을 시뮬레이션하면QueryException."크래쉬 시뮬레이션"을 위해 도커 컨테이너를 처리하는 도중에 정지합니다.원래의 직업은 아직도PendingJobTable그리고 다시 처리해야 합니다.@Startup.

내가 어떻게든 그를 잡을 수 있을까요?UnitOfWorkcrash 이후에도 계속 일을 할 수 있습니까?

예외:

Caused by: Exception [EclipseLink-6004] (Eclipse Persistence Services - 2.7.9.payara-p1): org.eclipse.persistence.exceptions.QueryException
Exception Description: The object [PendingJob], of class [class com.example.PendingJob], with identity hashcode (System.identityHashCod
e()) [948,982,881], is not from this UnitOfWork object space, but the parent session's. The object was never registered in this UnitOfWork, but read from the parent session and related to an object registered in the UnitOfWork.

플랫폼 정보

  • 자카르타 EE 플랫폼 9.1.0
  • 자바 11
  • 마리아DB jdbc
  • 파야라 애플리케이션 서버
  • 일반 JPA(동면 금지)

"솔루션"을 찾았습니다.

갱신하다

예외는 도커 컨테이너를 사용하여 "크래싱"하는 경우에만 발생합니다.docker-compose down, 진짜 충돌은 일어나지 않을 겁니다그러나 컨테이너를 죽이거나 다시 시작할 때 예외가 나타나지 않으며(애플리케이션이 의도한 대로 작동합니다).저는 여전히 예외를 고칠 방법을 찾으려고 노력할 것입니다.

나는 용기를 죽입니다.restart: on-failure) 사용하기docker ps컨테이너 ID 찾기:

docker ps

그런 다음 이 컨테이너가 실행 중인 프로세스를 확인합니다.

docker exec -it <container_id> ps -aux

jvm 프로세스(일부 pid)를 죽입니다.

docker exec -it <container_id> kill -9 <pid>

언급URL : https://stackoverflow.com/questions/73204589/unitofwork-exception-triggered-after-system-crash