2011-05-09 70 views
3

基於Spring的應用程序的寫入集成測試遇到事務回滾問題 - 插入數據,但事務回滾後,數據仍在數據庫表中... Spring 3.0.5,JUnit 4.8.2Spring集成測試事務不回滾

集成測試代碼

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:/applicationContext.xml" }) 
@TransactionConfiguration(transactionManager="txManager",defaultRollback=true) 
@Transactional 
public class GenerateCodeStrategyTest { 

    @Autowired 
    @Qualifier(value = "generateCodeStrategy") 
    private Strategy generateCodeStrategy; 

    @Test 
    @Transactional 
    public void genCodeIntegrationTestCommunicationFailure() { 
    //generate some parameters 
    SMPPSession mockedSession = mock(SMPPSession.class); 
    generateCodeStrategy.setSession(mockedSession); 
    generateCodeStrategy.sendRequest(params); 
    final SubscribeInfo subscribeInfo = subscribeDao.getUserByPhone(phone); 
    assertNotNull(subscribeInfo); 
    assertEquals(phone, subscribeInfo.getPhone()); 
    assertEquals(Status.BAD_STATUS, subscribeInfo.getStatus()); 
    } 
} 

在調試模式日誌中我可以看到交易開始並回滾

INFO: Began transaction (1): transaction manager [o[email protected]1edd9b3]; rollback [true] 
[main] DEBUG org.hibernate.SQL - insert into sms_subscribe (phone_cell, status, ts_subscribe, subscription_status, ts_unsubscribe, receiverIdentification, user_id) values (?, ?, ?, ?, ?, ?, ?) 
INFO: Rolled back transaction after test execution for test context [[[email protected] testClass = GenerateCodeStrategyTest, locations = array<String>['classpath:/applicationContext.xml'], testInstance = [email protected], testMethod = [email protected]est, testException = [null]]] 

也許有人知道爲什麼會發生這種情況?謝謝你的幫助。

更新: 該集成測試生成一些參數,然後使用會話對象的Mockito模擬插入策略服務。這個模擬對象只是拋出異常,在這個例外中,策略服務數據通過DAO層保存到數據庫。然後通過DAO層測試對數據庫的請求並聲明保存的值。

數據通過Hibernate進行持續所以基本上在我的DAO對象對象保存這樣

final Session currentSession = sessionFactory.getCurrentSession(); 
currentSession.save(object); 

SessionFactory的是AnnotationSessionFactoryBean其中數據源是C3P0 ComboPooledDataSource類

更新2:問題是與MySQL引擎,默認情況下它是MyISAM,所以我只需要將它切換到InnoDB,現在所有的工作。

+0

你能提供你的測試定義嗎? – 2011-05-09 09:04:01

回答

4

通常的問題是,您的服務層調用其他層也被標記爲@Transactional,甚至可能與REQUIRES_NEW。在這種情況下,Test偵聽器只能訪問外部事務,但無法回滾內部事務。

通常問題是在DAO層上有@Transactional註釋。如果有,請刪除它們。 DAO層應該沒有事務分界。

+0

我在DAO層中有@Transactional註解,所以我將它們全部刪除(現在我在服務層上有@Transactional - 在我的情況下,它是sendRequest服務方法,也在上面提到的集成測試中),但數據仍然在數據庫中運行成功。 – artjomka 2011-05-09 08:50:36

+1

@artjomka a)好的,您的服務層是否有REQUIRES_NEW?如果是這樣,它不能工作b)你如何堅持你的數據? Hibernate,JPA,JDBC?你可能是手動提交數據在DAO的某個地方? – 2011-05-09 09:22:06

+0

a)在服務層我有默認傳播值(REQUIRED)b)數據通過Hibernate持久化,dao使用sessionFactory保存對象(有問題更新)。謝謝你幫我解決這個案子。 – artjomka 2011-05-09 09:41:37

0

嘗試從類級別刪除@Transactional註釋,並僅將它留給特定的測試方法。

希望它有幫助。