며칠 동안이 문제로 고생하고 있으며 만족스럽지 못한 해결책을 찾을 수 없습니다. 아마도 다양한 수준의 간접 지정을 통해이 문제를 해결할 수 있지만, 내가 할 수 있어야하는 일종의 문제인 것처럼 보입니다. 내 문제가있을 수있는 몇 명의 다른 사람들을 찾았지만 그 중 아무도 정확한 답을 얻지 못하는 것 같습니다. 문제가 있거나 답변이 제공되지 않습니다.영속 참조가있는 개체를 지속 할 때 JPA와의 데이터베이스 교착 상태가 발생합니다.
이전에 Hibernate를 사용하여이 작업을 성공적으로 수행했지만 지금은 JPA로 작업 할 수 없었습니다.
사전 정보 다음 지속 확장을 사용
- Guice 3.0 애플리케이션 (주석/W) 최대 절전 모드와 (최대 5 개와 연결) C3P0. 우리는 공급자로부터 EntityManager를 주입하고 있으며이 과정에서 EntityManager 객체가 트랜잭션 객체와 동일하게 유지되는지 확인할 수 있습니다.
- 웹 애플리케이션의 일부로 설계된 현재의 문제점은 JUnit 및 dbUnit을 사용하는 자동화 된 통합 테스트에서만 발생합니다. 액세스는 싱글 톤 객체 (.in (Scopes.SINGLETON))에 대한 것이지만, 싱글 톤 객체는 인젝터에만 의존하고 @Transactional은 스레드로부터 안전합니다.
- 데이터베이스에는 주석이 달린 FileContainer에 매핑되는 파일 테이블과 개체 MIMEType에 매핑되는 MIME 형식 테이블이 있습니다. 응용 프로그램에서 새 파일을 만들 때 먼저 MIMEType 객체를 NamedQuery로 검색하고이를 유지합니다.
- 데이터베이스는 postgresql-8.4-702.jdbc3.jar을 사용하는 PostgreSQL 8.4입니다.
- 시스템은 실패한 상황에 대해 적당히 까다 롭습니다. 별도의 스레드를 생성하고 거기에서 액세스를 수행해야합니다.
번째 FileContainer 객체의 마임 필드 매핑은 다음
MIME 유형 객체로 주석이@ManyToOne(fetch=FetchType.EAGER, cascade={})
@JoinColumn(name="mimetype_id", referencedColumnName="id", nullable=false, updatable=true)
다음 :
@Entity
@Table(name="mimetypes")
@org.hibernate.annotations.Immutable
@Cacheable(true)
@NamedQuery(name="mt.ext", query="from MIMEType where extension = :ext",
hints= {@QueryHint(name="org.hibernate.fetchSize", value="1"),
@QueryHint(name="org.hibernate.readOnly", value="true")})
위의 모든 주석은 javax.persistence 버전입니다.
addFile
방법은 @com.google.inject.persist.Transactional
으로 주석됩니다. 이것을 클래스에 삽입 된 EntityManager를 사용하도록 변경하면 결과가 변경되지 않습니다.
객체를 생성하는 과정은 다음과 같이 진행됩니다
- 잡아 EntityManager를 인젝터에서 FileDAO. 이것들은 모두 공급자로부터 나옵니다.
- em.createNamedQuery ("mt.ext", MIMEType.class) .setParameter ("ext", extension)를 호출하여 데이터베이스에서 사용할 MIMEType 객체를 가져옵니다.getSingleResult();
- 가
FileContainer
객체를 생성하고`setMimetype (MIME 타입)에 대한 호출을 포함하여, 그것을 채울`개체와 우리는 단지FileContainer
객체의 기본 필드를 설정하고em.persist(Object)
를 호출 - 전화
dao.save(fileContainer)
를 검색. 이것을 DAO에서 빼내고EntityManager
을 먼저 주사해도 결과는 바뀌지 않습니다. 삽입이 발생하고 코드 교착 상태 - 즉시 (트랜잭션의 끝에서 또는 전에 그런 일이 어디든지)EntityManager.flush()
가 발생할 때이 시점에서
.
pg_stat_activity
을 확인하고 pg_locks
과 비교하면 insert 문이 "idle in transaction"연결에 의해 차단되고 대기 상태에 있음을 알 수 있습니다. MIMEType 삽입을 제거하고 (NULL을 허용하도록 열을 설정하면) 코드가 정상적으로 진행될 수 있으며 MIMEType의 값을 검사하면 올바르게 검색되었음을 나타냅니다.
의견이나 아이디어는 높이 평가됩니다.
EDIT :
이 계층이며, 희망이 동작들의 순서가 명확히하고 무슨된다
- 테스트 하니스 (를 초기화 인젝터와 특정 테스트에 주입하는 러너를 사용 클래스)
- 는 테스트 케이스는
- 는 스레드 ,369 시작
- 스레드 내에서 동일한 인젝터로 초기화 된 싱글 톤 객체에 트랜잭션 블록을 입력하면
EntityManager
객체가 모든 DAO 객체에서 동일하고 오류가 발생한 위치가 확인되었습니다. EntityManager
개체는injector.getInstance(EntityManager.class)
호출을 사용하거나Provider
개체를 획득하여 일관되게 수집됩니다.- 위의 과정을 모두 같은 스레드에서 수행하십시오. 코드는 표시되지 않습니다
flush()
에
물론, 상황을 명확히 할 수 있는지 알아 보겠습니다. –