복붙노트

[SPRING] 하나의 트랜잭션에서 Hibernate와 JDBC

SPRING

하나의 트랜잭션에서 Hibernate와 JDBC

@Transactional로 표시된 메소드가 있습니다. 이 함수는 여러 함수로 구성되며 그 중 하나는 JDBC를 사용하고 두 번째는 Hibernate, third JDBC를 사용합니다. 문제는 Hibernate 함수에 의해 만들어진 변경이 JDBC와 함께 작동하는 마지막 함수에서 보이지 않는다는 것입니다.

@Transactional
void update() {
  jdbcUpdate1();
  hibernateupdate1();
  jdbcUpdate2(); // results of hibernateupdate1() are not visible here    
}

모든 함수는 동일한 데이터 소스를 사용하도록 구성됩니다.

<bean id="myDataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
        <property name="targetDataSource" ref="targetDataSource"/>
    </bean>

    <bean id="targetDataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close" lazy-init="true" scope="singleton">
       <!-- settings here -->
    </bean>

myDataSource bean이 코드에서 사용됩니다. myDataSource.getConnection ()은 jdbc 함수 및

getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
               ... 
            }
        });

최대 절전 기능에 사용됩니다. 감사.

해결법

  1. ==============================

    1.먼저, 최대 절전 모드를 사용할 때 JDBC를 사용하지 마십시오.

    먼저, 최대 절전 모드를 사용할 때 JDBC를 사용하지 마십시오.

    그런 다음, 정말로 필요하다면 Session.doWork (..)를 사용하십시오. 최대 절전 모드 버전이 아직이 방법이 없다면, session.connection ()으로부터 Connection을 얻으십시오.

  2. ==============================

    2.올바른 Spring 설정을 사용하면 동일한 트랜잭션에서 JDBC와 Hibernate를 사용할 수 있습니다.

    올바른 Spring 설정을 사용하면 동일한 트랜잭션에서 JDBC와 Hibernate를 사용할 수 있습니다.

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    
    <bean id="myDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="target">
            <bean class="MyDaoImpl">
                <property name="dataSource" ref="dataSource"/>
                <property name="sessionFactory" ref="sessionFactory"/>
            </bean>
        </property>
        <property name="transactionAttributes">
            <props>
                <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
    

    이것은 DAO의 JDBC 부분이 JdbcTemplate을 사용한다고 가정합니다. 그렇지 않으면 몇 가지 옵션이 있습니다.

    후자는 프록시 데이터 소스 내부에 DataSourceUtils.getConnection을 숨겨 놓기 때문에 선호됩니다.

    이것은 물론 XML 경로이므로 주석 기반으로 쉽게 변환 할 수 있어야합니다.

  3. ==============================

    3.문제는 Hibernate 엔진에 대한 연산이 즉각적인 SQL 실행을 초래하지 않는다는 것입니다. Hibernate 세션에서 수동으로 flush를 호출하여 트리거 할 수 있습니다. 그런 다음 동일한 트랜잭션 내에서 최대 절전 모드로 변경된 내용을 SQL 코드에서 볼 수 있습니다. SQL 연결을 얻기 위해 DataSourceUtils.getConnection을 수행하는 경우에만 동일한 트랜잭션에서 이들을 실행할 수 있기 때문에 ...

    문제는 Hibernate 엔진에 대한 연산이 즉각적인 SQL 실행을 초래하지 않는다는 것입니다. Hibernate 세션에서 수동으로 flush를 호출하여 트리거 할 수 있습니다. 그런 다음 동일한 트랜잭션 내에서 최대 절전 모드로 변경된 내용을 SQL 코드에서 볼 수 있습니다. SQL 연결을 얻기 위해 DataSourceUtils.getConnection을 수행하는 경우에만 동일한 트랜잭션에서 이들을 실행할 수 있기 때문에 ...

    반대 방향으로, 이것은 더 까다 롭습니다. 왜냐하면 당신은 1 레벨 캐시 (세션 캐시)를 가질 것이고, 또한 아마도 2 차 레벨 캐시를 가지기 때문입니다. 2 차 레벨 캐시의 경우 데이터베이스에 대한 모든 변경 사항은 행이 캐시 된 경우 캐시가 만료 될 때까지 최대 절전 모드에서 볼 수 없습니다.

  4. from https://stackoverflow.com/questions/4153199/hibernate-and-jdbc-in-one-transaction by cc-by-sa and MIT license