2016-11-29 6 views
1

작동 코드를 롤백하지 않습니다 나는 @Rollback 주석을 사용하여 각 테스트 후 데이터베이스 상태를 롤백합니다. 불행히도 그것은 작동하지 않습니다. 기록이 남아 있기 때문에,봄 테스트의 @Rollback 아래 아무것도

//import everything 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = Test2.TestConfiguration.class) 
@Transactional 
public class Test2 { 

    @Autowired 
    private DataSource datasource; 

    @BeforeTransaction 
    public void createTable() throws SQLException { 
     datasource .getConnection() 
        .createStatement() 
        .execute("CREATE TABLE USERS (id bigint, size bigint, primary key (id))"); 
    } 

    @Rollback 
    @Test 
    public void test() throws SQLException { 
     datasource .getConnection() 
        .createStatement() 
        .execute("INSERT INTO USERS VALUES (5, 5)"); 
    } 

    @AfterTransaction 
    public void dropTable() throws SQLException { 
     ResultSet rs = datasource .getConnection() 
            .createStatement() 
            .executeQuery("SELECT * FROM USERS"); 
     boolean isEmpty = !rs.next(); 
     if (isEmpty) { 
      System.out.println("Rollback succeeded"); 
     } else { 
      System.out.println("Rollback failed"); 
     } 
     rs.close(); 

     datasource .getConnection() 
        .createStatement() 
        .execute("DROP TABLE USERS"); 
    } 

    @Configuration 
    public static class TestConfiguration { 

     @Bean 
     public DataSource driverManagerDataSource() { 
      DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(); 
      String dbURI = "database/tests/DerbyDB/db"; 
      String connectionString = "jdbc:derby:" + dbURI; 
      if (!new File(dbURI).exists()) connectionString += ";create=true"; 
      driverManagerDataSource.setUrl(connectionString); 
      driverManagerDataSource.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver"); 
      return driverManagerDataSource; 
     } 

     @Bean 
     public PlatformTransactionManager platformTransactionManager() { 
      PlatformTransactionManager ptm = new DataSourceTransactionManager(driverManagerDataSource()); 
      return ptm; 
     } 
    } 
} 

봄 그것이 사실이 아니다 데이터베이스를 롤백 주장 :

여기 내 테스트 클래스입니다.
어떻게 작동합니까?

gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext startTransaction 
INFO: Began transaction (1) for test context [[email protected] testClass = Test2, testInstance = [email protected], testMethod = [email protected], testException = [null], mergedContextConfiguration = [[email protected] testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [o[email protected]3bf9ce3e]; rollback [true] 
gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext endTransaction 
INFO: Rolled back transaction for test context [[email protected] testClass = Test2, testInstance = [email protected], testMethod = [email protected], testException = [null], mergedContextConfiguration = [[email protected] testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]. 
Rollback failed 
gru 01, 2016 12:26:14 PM org.springframework.context.support.GenericApplicationContext doClose 
INFO: Closing [email protected]45eb6: startup date [Thu Dec 01 12:26:12 CET 2016]; root of context hierarchy 

전체 로그가 아래에 제시되어

gru 01, 2016 12:26:12 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames 
INFO: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener] 
gru 01, 2016 12:26:12 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners 
INFO: Using TestExecutionListeners: [or[email protected]69d9c55, org.springframework.test[email protected]13a57a3b, org.springframewor[email protected]7ca48474, org.springfra[email protected]337d0578, org.springframew[email protected]59e84876, org.sp[email protected]61a485d2] 
gru 01, 2016 12:26:12 PM org.springframework.context.support.GenericApplicationContext prepareRefresh 
INFO: Refreshing [email protected]45eb6: startup date [Thu Dec 01 12:26:12 CET 2016]; root of context hierarchy 
gru 01, 2016 12:26:13 PM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init> 
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring 
gru 01, 2016 12:26:13 PM org.springframework.jdbc.datasource.DriverManagerDataSource setDriverClassName 
INFO: Loaded JDBC driver: org.apache.derby.jdbc.EmbeddedDriver 
gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext startTransaction 
INFO: Began transaction (1) for test context [[email protected] testClass = Test2, testInstance = [email protected], testMethod = [email protected], testException = [null], mergedContextConfiguration = [[email protected] testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [o[email protected]3bf9ce3e]; rollback [true] 
gru 01, 2016 12:26:14 PM org.springframework.test.context.transaction.TransactionContext endTransaction 
INFO: Rolled back transaction for test context [[email protected] testClass = Test2, testInstance = [email protected], testMethod = [email protected], testException = [null], mergedContextConfiguration = [[email protected] testClass = Test2, locations = '{}', classes = '{class tyvrel.tastas.persistence.Test2$TestConfiguration}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]. 
Rollback failed 
gru 01, 2016 12:26:14 PM org.springframework.context.support.GenericApplicationContext doClose 
INFO: Closing [email protected]45eb6: startup date [Thu Dec 01 12:26:12 CET 2016]; root of context hierarchy 

답변

2

내가 이해, 당신은 초기화하는 동안 테이블을 생성하여 시험 방법, 수동으로 새로운 독립적 인 Spring 컨텍스트를 만드는에서.

해당 컨텍스트는 고유 한 트랜잭션 관리자와 데이터 소스를 사용하기 때문에 @Rollback 주석의 영향을받지 않습니다. 즉, 전체 테스트 클래스에 대해 정의 된 (암시 적) 스프링 컨텍스트의 컨텍스트에서 처리됩니다.


또한 일부 데시벨, 당신은 CREATE 명령 (하지만 더비에 대해 확실하지)를 롤백 할 수 있습니다.

또 다른 문제


업데이트는 datasource.getConnection()을 통해 연결을 얻을 때 실제로 트랜잭션 관리자를 사용하지 않을 것입니다. DataSourceTransactionManager 문서에서

:

응용 프로그램 코드가 아닌 표준 Java EE 스타일 DataSource.getConnection() 통화 DataSourceUtils.getConnection(DataSource)를 통해 JDBC 연결을 검색하는 데 필요합니다. JdbcTemplate과 같은 스프링 클래스는이 전략을 암시 적으로 사용합니다.

+0

당신은'@ContextConfiguration (classes = TestDerbyDatabaseInitializer.TestConfiguration.class)'로 주석 클래스를 테스트하고 implict 컨텍스트를 삭제하면'@ Rollback' 주석이 작동한다는 것을 의미합니까? – Tyvrel

+1

1)'@ ContextConfiguration' 주석에 의해 생성 된 Spring 컨텍스트를 사용해야한다. 혼동을 피하기 위해 다른 컨텍스트를 만들지 마라. 2) 우연히 관리되지 않는 연결을 사용하지 않기 위해 프로그래밍 방식으로 ("DriverManager.getConnection()") 데이터베이스에 대한 다른 연결을 만들지 말라. 3) 알고있는 것을 테스트한다. 롤백 할 수 있습니다 (예 :'INSERT'가 아니라'CREATE TABLE') -'@ BeforeTransaction' 메소드로 데이터베이스를 생성합니다. –

+0

감사합니다. 그 답을 통해 Spring 테스트에 대해 더 많이 이해하게되었습니다. 또한 귀하의 의견에 따라 코드가 업데이트되었지만 여전히 작동하지 않습니다. – Tyvrel

0

나는이 라인 con.close();에서 printTableName() 방법이 issuse을 일으킨 것 같아요.

연결을 닫을 때 트랜잭션이 커밋됩니다.

트랜잭션을 처리하려면 entitymanager 또는 spring data jpa repository을 사용하는 것이 더 좋습니다.

+0

Unfortunatelly,'con.close();를 삭제해도 문제가 해결되지 않는다. – Tyvrel

+0

@Tyvrel 명시 적으로 롤백을 시도 했습니까? 'con.rollback();' – Bryan

+0

물론. 그것도 작동하지 않습니다. 요점을 놓친다 - @ 롤백이 어떻게 작동 하는지를 배우고 간단한 SQL 스크립트를 실행하는 것보다 쉬운 방법을 찾아 낼 수 없었다. – Tyvrel