Whiteship's Note


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

Spring/Chapter 8 : 2008.02.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


@Transactional 속성들

Spring/Chapter 9 : 2007.04.15 08:43


사용자 삽입 이미지
아직 name 속성은 없습니다. name 속성을 사용해서 로깅이나 트랜잭션 모니터링을 할 때 트랜잭션 이름을 원하는 이름으로 출력할 수 있을 겁니다. 하지만 지금은 "패키지 경로가 붙은 클래스 이름.해당 메소드"가 기본 이름이 됩니다.

Property

Type

Description

propagation

enum: Propagation

optional propagation setting

isolation

enum: Isolation

optional isolation level

readOnly

boolean

read/write vs. read-only transaction

timeout

int (초 단위)

the transaction timeout

rollbackFor

Throwable 타입의 Class 객체의 배열

발생했을 때 반드시 롤백 해야 하는 예외 클래스들

rollbackForClassname

Throwable 타입의 Class 이름의 배열

발생했을 때 반드시 롤백 해야 하는 예외 클래스들의 이름

noRollbackFor

Throwable 타입의 Class 객체의 배열

발생했을 때 롤백 하지 않아도 되는 예외 클래스들.

noRollbackForClassname

Throwable 타입의 Class 이름의 배열

발생했을 때 롤백 하지 않아도 되는 예외 클래스들의 이름


top