Whiteship's Note

스프링에서 하이버네이트와 JDBC 같이 사용할 때 트랜잭션 처리는?

Hibernate/etc : 2008.10.08 16:23


별로 할 일이 없습니다.

PlatformManager는 하이버네이트가 사용하는
org.springframework.orm.hibernate3.HibernateTransactionManager

이걸 그대로 사용하면 되고, JDBC 코딩을 할 때는 그냥 JdbcTemplate을 사용하면 알아서 트랜잭션이 적용됩니다.

그런데 만약에 JdbcTemplate을 사용하지 못하고, DataSource를 직접 사용해야 할 경우에는 다음과 같이 TransactionAwareDataSourceProxy를 사용하면 된다고 합니다.

<bean id="rawDataSource" class="whatover youuse"/>

<bean id="dataSource" class="TransactionAwareDataSourceProxy">
  <constructor-arg ref="rawDataSource" />
</bean>

DataSource를 직접 사용하는 코드가 엄청나게 많아서 손을 못댈 경우에는 저렇게 dataSource를 스프링이 관리하는 트랜잭션을 알고 있는 데이터소스로 바꾸면 된다고 하는데, 해보진 않았습니다. 제가 해보고 싶었던 건 하이버네이트가 flush()를 하지 않은 데이터에 대한 JDBC쿼리로 인한 예외 상황인데...

테스트를 잘못 짠건지.. 잘 안 되더군요.

@Repository
public class MemberDao {

    @Autowired
    SessionFactory sessionFactory;
   
    SimpleJdbcTemplate jdbcTemplate;
   
    @Autowired
    public MemberDao(DataSource dataSource) {
        jdbcTemplate = new SimpleJdbcTemplate(dataSource);
    }
   
    public void add(Member member){
        sessionFactory.getCurrentSession().save(member);
    }
   
    public int update(Member member){
        return jdbcTemplate.update(
                "UPDATE Member SET age = ? WHERE name = ?", member.getAge(), member.getName());
    }

}

이런 DAO를 만들었습니다. add()는 하이버네이트로하고 update()는 JdbcTemplate으로 했습니다.

@Service
@Transactional
public class MemberService {

    @Autowired
    MemberDao memberDao;
   
    public void foo(){
        Member member = new Member();
        member.setName("keesun");
        memberDao.add(member);
       
        member.setAge(20);
        memberDao.update(member);
    }
   
}


그리고 서비스 코드는 저렇게 트랜잭션 처리를 하고, keesun이라는 객체를 하나 만들어서 저장하고, 나이를 추가한다음에 JDBC로 update문을 날립니다.

제가 원했던 결과는..

에러가 나는 겁니다.

그러나..

Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into Member (age, name, id) values (?, ?, ?)
Hibernate: update Member set age=?, name=? where id=?

에러가 나질 않고, 너무도 자연스럽게 동작해버려서 당황했습니다. 특히 마지막 줄의 쿼리는 제가 JdbcTemplate으로 날린 쿼리랑은 완전 다른 하이버네이트가 만든 쿼리가 날아갔습니다. 이게 대체;;; 무슨 일인지..  흠..

결과적으로는 아~무 걱정없이 하이버네이트랑 JdbcTemplate을 같이 사용할 수 있다는 것이지만, 제가 원했던 상황이 발생하지 않아서 좀 우울합니다.
top




: 1 : ··· : 6 : 7 : 8 : 9 : 10 : 11 :