Spring单元测试用例没有回滚插入记录
Posted
技术标签:
【中文标题】Spring单元测试用例没有回滚插入记录【英文标题】:Spring unit test case is not rolling back insertion of a record 【发布时间】:2011-06-26 17:56:15 【问题描述】:以下测试用例在功能上正常工作,但必须在数据库中创建新文章的测试方法之一在测试用例执行结束时不会回滚。 我希望它以这种方式工作。对于更新文章的测试用例实际上会在测试用例执行结束时回滚更新。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "/applicationContext-test.xml")
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = true)
@Transactional
public class PriceRepositoryTest
@Resource(name ="repository")
private PriceRepository repository;
@Test
public void testGetAll() throws Exception
Assert.assertEquals(8, repository.getAll().size());
@Test
@Rollback
public void shouldSaveNewArticle()
Article article = new Article();
article.setName("Article");
article.setPrice(33);
repository.save(article);
Assert.assertEquals(9, repository.getAll().size());
@Test
@Rollback
public void shouldUpdateArticle()
Article article = repository.getArticle(4);
article.setPrice(33);
repository.update(article);
Assert.assertEquals(String.valueOf(33.0), String.valueOf(repository.getArticle(4).getPrice()));
【问题讨论】:
【参考方案1】:您的 DAO 是否也标有 @Transactional
?如果是,那就是问题所在:不同层上的事务性不知道您的本地事务配置。
如果repository.update(article)
是@Transactional
,它可能会或可能不会启动一个新事务(取决于propagation
属性的值),但它会在执行后提交事务,并且您的测试方法无法拦截那个。
这就是为什么应该在服务级别而不是 DAO 级别启动事务的原因之一。
(如果不是这样,我谦虚地道歉)
【讨论】:
如果您实际查看代码,更新和保存方法都标记为 Propagation.REQUIRED。 @Antony 看到这些问题:***.com/questions/1079114/…***.com/questions/3886909/…【参考方案2】:我也遇到了这个问题,并花了几个小时试图找到根本原因。该问题是此处描述的问题的变体。在我的例子中,应用程序通过 Spring 调用存储过程,其中一个过程包含 COMMIT
语句。
提交应该始终由应用程序控制,如果在存储过程中的某处存在杂散提交,Spring 无法控制事务并且测试不会回滚。
【讨论】:
【参考方案3】:我刚刚遇到这个问题,我的单元测试全部设置为回滚,测试完成后我的记录仍然显示在数据库中。原因是在 DAO 中,对实体管理器的 flush() 调用在方法中——这迫使事务提交。
em.persist(jpaServer); em.flush(); //无论spring设置做什么都提交记录
取出冲洗并确认没有记录。用 @Rollback(false) 注释的测试测试了相同的代码并确认记录(证明不需要刷新)
本 www.nimbits.com【讨论】:
flush() 会将挂起的更新推送到数据库,但它不会强制提交,它们仍应回滚(除非您启用了自动提交)以上是关于Spring单元测试用例没有回滚插入记录的主要内容,如果未能解决你的问题,请参考以下文章
用于 RowMapper 的 Spring jdbc 模板的单元测试用例