문제

질문이 너무 길어서 양해해 주시기 바랍니다.

우리는 웹 애플리케이션에 Spring+JPA를 사용하고 있습니다.우리 팀은 주사를 두고 논쟁 중이야 EntityManagerFactory 에서 GenericDAO (APPFUSE에서 제공하는 라인의 Generics를 기반으로 한 DAO, 우리는 사용하지 않습니다. JpaDaosupport 어떤 이유로) 과다 주입 EntityManager.우리는 "애플리케이션 관리 지속성"을 사용하고 있습니다.

주사를 반대하는 주장 EntityManagerFactory 너무 무거워서 필요하지 않다는 점, EntityManager 우리에게 필요한 일을 합니다.또한 Spring은 모든 웹 요청에 대해 DAO의 새 인스턴스를 생성하므로(이건 의심스럽습니다) 동일한 동시성 문제는 발생하지 않습니다. EntityManager 인스턴스는 두 개의 스레드에 의해 공유됩니다.

EFM 주입에 대한 주장은 공장에 대한 핸들을 갖는 것이 항상 좋은 것보다 좋은 습관이라는 것입니다.

어느 것이 최선의 접근 방식인지 잘 모르겠습니다. 누군가 제게 알려주실 수 있나요?

도움이 되었습니까?

해결책

EntityManagerFactory와 EntityManager를 주입하는 것의 장단점은 모두 Spring 문서에 나와 있습니다. 여기, 제가 ​​그 점을 개선할 수 있을지 잘 모르겠습니다.

그렇다면 귀하의 질문에는 해결해야 할 몇 가지 사항이 있습니다.

... Spring은 모든 웹 요청에 대해 새로운 DAO 인스턴스를 만듭니다 ...

이것은 정확하지 않습니다.DAO가 Spring 빈인 경우 다음을 통해 달리 구성하지 않는 한 싱글톤입니다. scope Bean 정의의 속성.모든 요청에 ​​대해 DAO를 인스턴스화하는 것은 미친 짓입니다.

EMF를 주입한다는 주장은 공장에 대한 손잡이를 갖는 것이 항상 좋은 실습이라는 것입니다.

이 주장은 실제로 설득력이 없습니다.일반적인 모범 사례에 따르면 개체에는 해당 작업을 수행하는 데 필요한 최소한의 협력자가 주입되어야 합니다.

다른 팁

나는 내가 마침내 모은 것을 내려 놓고있다. 섹션에서 "일반 JPA를 기반으로 DAO 구현"스프링 참조에서 :

EntityManagerFactory 인스턴스는 스레드 안전이지만 EntityManager 인스턴스는 그렇지 않습니다. 주입 된 JPA EntityManager는 JPA 사양에 의해 정의 된대로 애플리케이션 서버의 JNDI 환경에서 가져온 EntityManager처럼 동작합니다. 그것은 모든 통화를 현재 트랜잭션 엔티티 매너에 위임합니다. 그렇지 않으면 작동 당 새로 생성 된 EntityManager로 돌아가서 실제로 사용 스레드 안전을 만듭니다.

이는 JPA 사양에 따라 EntityManager 인스턴스가 스레드 안전하지 않지만 스프링을 처리하면 스레드를 안전하게 안전하게 만들 수 있습니다.

Spring을 사용하는 경우 EntityManagerFactory 대신 EntityManagers를 주입하는 것이 좋습니다.

나는 이것이 이미 잘 덮여 있다고 생각하지만 몇 가지 점을 강화하기 위해서.

  • DAO, 봄에 주입하면 기본적으로 싱글 톤입니다. 매번 새 인스턴스를 만들려면 스코프를 프로토 타입으로 명시 적으로 설정해야합니다.

  • @PersistEnceContext에 의해 주입 된 엔티티 관리자 스레드 안전합니다.

즉, 나는 멀티 스레드 애플리케이션에서 Singleton Dao에 몇 가지 문제가있었습니다. 나는 결국 DAO를 Instanced Bean으로 만들었고 그 문제를 해결했습니다. 따라서 문서가 한 가지 말을 할 수 있지만 응용 프로그램을 철저히 테스트하고 싶을 것입니다.

후속 조치 :

내 문제의 일부는 내가 사용하고 있다는 것입니다.

@PersistenceContext(unitName = "unit",
    type = PersistenceContextType.EXTENDED)

PersistEnceContextType.extended를 사용하는 경우 올바르게 이해하면 트랜잭션을 수동으로 닫아야합니다. 보다 이것 자세한 내용은 스레드입니다.

다른 후속 조치 :

Instanced DAO를 사용하는 것은 매우 나쁜 생각입니다. DAO의 각 인스턴스에는 고유 한 지속성 캐시가 있으며 하나의 캐시 변경은 다른 DAO 콩에 의해 인식되지 않습니다. 나쁜 조언에 대해 죄송합니다.

DAO에 @repository 스프링 주석을 설정하고 Spring에 의해 EntityManager를 관리하고 @PersistEnceContext 주석에 의해 주입되는 것이 모든 것을 유창하게 작동시키는 가장 편리한 방법이라는 것을 알았습니다. 공유 EntityManager의 스레드 안전 및 예외 번역의 혜택을 누릴 수 있습니다. 기본적으로 공유 EntityManager는 예를 들어 관리자의 여러 DAO를 결합하면 트랜잭션을 관리합니다. 결국 당신은 당신의 daos가 빈혈이 될 것임을 알게 될 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top