2012-11-09 4 views
1

동일한 테이블에서 두 개의 데이터베이스 연산을 수행하는 Spring 서비스 메소드가있다. 하나는 Hibernate Session Factory이고 다른 하나는 평범한 Spring JDBC이다. 그러나 둘 다 단일 트랜잭션에 바인딩되기를 원합니다. 아래 코드에서는 2 개의 다른 트랜잭션이 생성되고 첫 번째 트랜잭션이 두 번째 트랜잭션에 대해 테이블을 잠그는 것처럼 보입니다.동일한 테이블에서 동일한 트랜잭션의 springjdbc와 hibernate 세션 팩토리를

두 작업이 모두 단일 트랜잭션으로 처리되는지 어떻게 확인합니까? ?

내 서비스 클래스

@Service 
public class MyService{ 

@Autowired 
IMyDao mydao; 

@Transactional 
public void myMethod(){ 
...  
mydao.save(entity); //This uses hibernate 
... 
mydao.saveBulk(List<Entity> entities>; //This uses spring jdbc for performance reasons. 
} 

... 
} 

MyDAOImpl.class

public class MyDAOImpl extends SimpleJDBCSupport implements IMyDao{ 
    private SessionFactory sessionFactory; 

@Autowired 
public MyDAOImpl (
     @Qualifier("sessionFactory") final SessionFactory sessionFactory, 
     @Qualifier("dataSource") final DataSource dataSource) { 
    this.sessionFactory = sessionFactory; 
    this.setDataSource(dataSource); 
} 
    public void save(Entity entity){ 
     sessionFactory.getCurrentSession().createQuery("insert into tableA... ").executeUpdate() ; 


    } 
    public void saveBulk(List<Entity> entites){ 
     ...// prepare batch insert data. 
     this.getJdbcTemplate().batchUpdate("insert into tableA... " , batchPreparedStmtSetter) 

    } 
} 

봄 구성

<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"> 
    <property name="xaDataSourceClassName" value="${advdb.jdbc.dataSourceClassName}" /> 
    <property name="xaProperties" ref="dataSourceProperties" /> 
    <property name="uniqueResourceName" value="${advdb.jdbc.uniqueResourceName}" /> 
    <property name="testQuery" value="${advdb.jdbc.testQuery}" /> 
    <property name="minPoolSize" value="${advdb.jdbc.minPoolSize}" /> 
    <property name="maxPoolSize" value="${advdb.jdbc.maxPoolSize}" /> 
    <property name="maxIdleTime" value="${advdb.jdbc.maxIdleTime}" /> 
    <property name="borrowConnectionTimeout"  value="${advdb.jdbc.borrowConnectionTimeout}" /> 
    <property name="reapTimeout" value="${advdb.jdbc.reapTimeout}" /> 
    <property name="maintenanceInterval" value="${advdb.jdbc.maintenanceInterval}" /> 
</bean> 

<!-- Session Factory --> 

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" p:dataSource- ref="dataSource"> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
      <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> 
      ... 
          ... 
</bean> 
+0

삽입을 수행하기 위해 "update (...)"메소드 대신 "createQuery (...)"를 사용하고 있기 때문일 수 있습니다. –

+0

나는 그 영향을 몰랐다. 그러나 나는 그것을 시도 할 것이다. –

답변

1

TRANSA 경계는 사용되는 연결에 의해 제어됩니다. 동일한 연결 (동일한 Hibernate Session 인스턴스, 동일한 JPA 엔티티 관리자 인스턴스 또는 동일한 Spring JdbcTemplate이 될 수있는)을 사용하는 한이 연결에서 독점적으로 잠긴 테이블은 현재 연결에서 트랜잭션이 발생할 때까지 다른 사용자가 사용할 수 없습니다 커밋되거나 롤백됩니다.

일반적인 저장 및 대량 저장을 위해 다른 연결 (HibernateSessionSimpleJdbcTemplate 통해)을 사용하고 있기 때문에 동일한 트랜잭션의 일부가 될 수 없습니다. 두 동작을 차례로 직렬화해야합니다.

+0

흠 .. 재밌 네요, 단위 테스트의 일부로 같은 서비스를 호출 할 때 똑같은 트랜잭션을 사용합니다. 다시 말하지만, 저는 같은 스프링 구성을 사용하고 있습니다. 어떤 아이디어 ..? –

+1

나는 HibernateTransactionManager를 사용하여이 문제를 해결했다. –