2011-05-09 111 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注释,并仅将它留给特定的测试方法。

希望它有帮助。