2009-04-30 3 views
1

여기서 '범위'가 올바른 용어인지 확실하지 않습니다.@Transactional의 범위를 최소화하고 싶습니까?

JPA 트랜잭션 관리를 위해 Spring을 사용하고 있습니다 (최대 절전 모드 상태). 데이터베이스 트랜잭션을 미리 형성하는 내 방법은 개인이지만, 당신은 단지 클래스 또는 public method

에 @Transactional을 설정할 수 있기 때문에이 메커니즘은 프록시에 전용 '외부'방법은 프록시를 통해 들어오는 호출을 기반으로하므로 것 도청 당한다. 즉, 대상 객체의 다른 메소드를 호출하는 대상 객체 내의 메소드 인 '자체 호출'은 호출 된 메소드가 @Transactional로 표시 되더라도 런타임시 실제 트랜잭션으로 이어지지 않습니다!

클래스의 공개 진입 점을 @Transactional로 설정했습니다.

@Transactional 
public void run(parameters) { 
    //First non-database method, takes a decent amount of time 
    Data data = getData(); 
    //Call to database 
    storeData(data); 
} 

private storeData(data) { 
    em.persist(data); 
} 

이것은 나쁜 습관입니까? Spring은 여기에서 더 오래 필요로하는 열린 트랜잭션을 유지합니까? storeData() 메서드를 DAO 클래스로 이동하여 공용으로 만들 생각 이었지만 학문적으로 대중에게 리팩토링하면 성능상의 이점이 있는지 알고 싶었습니다.

+0

나는 두 가지 대답을 가지고 있습니다. 내가 올바르게 이해하면 반대되는 말을하고 있습니다. 다른 누구도이 질문에 무게를 둘 수 있습니까? –

+0

질문과 관련하여 http://stackoverflow.com/questions/1079114가 있습니다. –

답변

1

DB에 과도한 경합이있는 경우 가능한 한 작게 트랜잭션을 유지하는 것이 확실히 중요합니다. 공용 및 개인별 구분보다 훨씬 중요합니다. 그 자체로 성능 및 확장성에 영향을주지 않습니다. 그래서 실용적으로 ...!

+0

내 질문에 오해 한 것 같아. @ 트랜잭션은 public 메소드에서만 존재할 수 있지만, 나는 데이터베이스 작업 만하는 메소드에 @Transactional을 제한해야한다. –

+1

나는 이해했다 : 우리는 실제로 트랜잭션 범위를 가능한 한 엄격하게 제한해야하며, 이는 공개하지 않는 것을 공개하는 것이 의미하는 것이면 그것은 세상 끝이 아님을 의미한다. –

1

트랜잭션 범위는 트랜잭션 컨텍스트 (이 경우 storeData() 메서드)와 상호 작용할 때까지 아무런 효과가 없습니다. storeData()에 도달 할 때만 데이터베이스 잠금이 발생하기 때문에 getData()가 비 트랜잭션 (non-transactional)이라는 사실은 코드의 동시성 성능에 영향을 주어서는 안됩니다.

+0

트랜잭션 격리 수준에 따라 다릅니다. SERIALIZABLE 격리를 사용하면 다른 트랜잭션의 커밋이 읽기 작업에 영향을 미치지 않도록 데이터베이스가 트랜잭션 시작시 상태를 추적해야합니다. – andri

+0

@andri 언제 거래가 시작됩니까? 스카프맨이 em.persist에게 전화 할 때까지 시작하지 않는다고 생각한 것 같아요? –

+1

데이터베이스에 관한 한, 트랜잭션은 데이터베이스에 대한 연결이 확보 된 경우에만 시작됩니다. storeData() 메서드가 호출 될 때까지이 작업이 수행되지 않으면 데이터베이스와 관련하여 트랜잭션이 시작됩니다. 연결이 포함되기 전에 데이터베이스는 관련이없고 알려지지도 않습니다. – skaffman

관련 문제