Whiteship's Note

통합 테스트에서 @Transactional이 먹지 않는 경우

Spring/Chapter 8 : 2008. 2. 20. 13:49


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@TransactionConfiguration(defaultRollback=true)
@Transactional
public class DomainTest {
    
    @Autowired
    private SessionFactory sessionFactory;

    @Test
    public void tadd() throws Exception {
        assertNotNull(sessionFactory);
        Session session = sessionFactory.openSession();

        BankAccount bankAccount = new BankAccount();
        bankAccount.setOwner("keesun");
        bankAccount.setAccount("123123");
        session.save(bankAccount);

        session.flush();
        session.close();

        assertNotNull(bankAccount.getId());
    }

    @Test
    public void atransacctional() throws Exception {
        Session session = sessionFactory.openSession();

        List<BankAccount> bankAccounts = session.createQuery("from BankAccount").list();
        assertEquals(0, bankAccounts.size());

        session.flush();
        session.close();
    }
}

테스트 이름을 보면 뭔가 이상하다는 것을 느끼실 겁니다. add 앞에 t를 붙여놨고, transactional앞에 a를 붙여놨습니다. 그냥 테스트 하면 transactional 테스트 코드를 먼저 실행하고 그 뒤에 add를 실행하기 때문에 저 테스트 코드가 정말 트랜잭션 처리가 됐는지 안 됐는지 확인 할 수가 없습니다. 더군다나 메모리 모드로 HSQL을 사용하고 있기 때문에 테스트를 한 번 실행하고 나면 데이터는 어차피 날아갑니다. 그래서 add가 먼저 실행되게 이름을 좀 이상하게 바꿔놨습니다.

그랬더니... 트랜잭션 처리가 되지 않는 것이 확인 되었습니다. 테이블에서 데이터 전부 가져오면 갯수가 0이어야 하는데, 1인 것입니다. add에서 하나 집어 넣은게 롤백되지 않았다는 것입니다.

대체 왜...

내가 뭘 잘못했길래...

애노테이션이 이상한가.. 싶어서 AbstractTransactional어쩌구저쩌구 클래스를 가지고도 테스트 해봤습니다. 여전히..  트랜잭션이 먹히지 않습니다.

bean 설정은 다음과 같습니다.

    <bean class="chapter7.polymorphic.tpccWithImplicitPolymorphism.DomainTest" />

    <bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
        <property name="url" value="jdbc:hsqldb:mem:test" />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.HSQLDialect
                </prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.connection.autocommit">false</prop>
            </props>
        </property>
        <property name="annotatedClasses" ref="annotatedClasses" />
    </bean>

    <util:list id="annotatedClasses">
        <value>chapter7.polymorphic.tpccWithImplicitPolymorphism.BankAccount</value>
        <value>chapter7.polymorphic.tpccWithImplicitPolymorphism.BillingDetails</value>
        <value>chapter7.polymorphic.tpccWithImplicitPolymorphism.CreditCard</value>
    </util:list>
   
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager"
        p:dataSource-ref="dataSource" p:sessionFactory-ref="sessionFactory" />
       
</beans>

정답은 안 갈쳐줍니다. 캬캬캬캬캬

힌트.
자바 소스 코드는 문제가 없으며,
경로 설정이라든가,
오타로 인한 문제도 아닙니다.
http://forum.springframework.org/showthread.php?t=16884
top

  1. sharp00k 2008.12.16 19:08 PERM. MOD/DEL REPLY

    transactionManager 등록이 안된거 같네요 ^^

    Favicon of http://whiteship.me BlogIcon 기선 2008.12.16 19:34 PERM MOD/DEL

    맨 마지막에 등록되어 있어요 ㅋㅋ

  2. 항해사 2009.09.14 16:17 PERM. MOD/DEL REPLY

    저 같은 경우에
    DB 를 Mysql 을 썻는데
    table type 을 myisam 으로 했더니 안되더군요
    innodb 로 type 변경 하니 잘 되었습니다.

    Favicon of http://whiteship.me BlogIcon 기선 2009.09.14 16:35 PERM MOD/DEL

    하두 오래되서 저도 왜 그랬는지 기억이 안났었는데, 본문 맨 마지막에 감춰둔 링크를 보니까, 항해사님과 같은 경우 같습니다. myisam은 트랜잭션을 지원하지 않더군요. 로우레벨에서 아예 지원하지 않는 기능인지라 아무리 @Trasactional을 설정해도 통하지 않았던 것입니다. 맞추셨습니다!! 짝짝짝!!!

Write a comment.