5

这是我的测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:repositoryContextTest.xml" })
@Transactional
@TransactionConfiguration(defaultRollback = true)
public class SeasonITest {
@Autowired
private SeasonDao seasonDao;

@Test
public void createSeason() throws Exception {
    Season season = new Season();
    season.setName("2012");
    seasonDao.createSeason(season);
}

以及我的 bean 配置文件中的 dataSource

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost/tournament_system" />
    <property name="username" value="root" />
    <property name="password" value="root" />
    <property name="defaultAutoCommit" value="false"/>
    <property name="poolPreparedStatements" value="false"/>
    <property name="maxOpenPreparedStatements" value="0"/>
 </bean>

<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

当我运行此测试时,会在我的数据库中创建一条新记录。

我怎样才能回滚这个事务?

这是我看到的日志输出:

2012-06-15 15:00:02,173 [main] INFO  - ionalTestExecutionListener - 
 Rolled back transaction after test execution for test context 
 [[TestContext@76db09 testClass = SeasonITest, 
   locations = array<String>['classpath:repositoryContextTest.xml'], 
   testInstance = org.toursys.repository.dao.SeasonITest@1265109, 
   testMethod = createSeason@SeasonITest, testException = [null]]]

更新:

下面的所有答案都想改变我不想要的逻辑或数据库引擎。所以我提供正确答案的声誉点:

为什么当我有这个时: @TransactionConfiguration(defaultRollback = true)在事务配置测试中没有回滚以及如何修复它?

4

9 回答 9

7

如果您使用 MySQL 和 MyISAM 引擎,请尝试切换到 InnoDB。

对于更复杂的测试,您可能需要一个模拟框架或数据库重建。

EDIT1:根据文档,InnoDB 是事务性的,具有完整的 ACID 支持,而 MyISAM 支持原子操作。更多阅读:事务和原子操作的区别

EDIT2:在@TransactionConfiguration 中,defaultRollback 的默认值为 true,因此您应该添加 @TransactionConfiguration(defaultRollback=false) 而不是注释该行

于 2012-06-15T13:19:56.240 回答
1

从表面上看,您的代码和配置看起来是正确的。但是,能否请您发布您的 SeasonsDAO 对象。我们首先需要验证 SeasonsDAO 是否为交易正确配置。

SeasonsDAO 需要参与与您的测试用例相同的 TransactionContext,并且无法使用您发布的代码进行验证。

您是否将 SeasonsDAO 标记为 @Transactional ?

如果不是,我不确定 TransactionProxyFactoryBean 将如何代理和以声明方式管理事务。

在高层次上,spring 使用代理的概念来执行许多服务,例如事务管理。

如果您将某些内容标记为@Transactional,Spring 将动态创建一个代理,该代理将实现与您的目标类相同的接口。一旦被代理,事务拦截器将包​​装对目标类的方法调用,并根据您可能指定的默认值或规则决定是回滚还是提交。

于 2012-06-19T20:30:03.177 回答
0

在您的测试用例逻辑之后尝试以下方法。

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
于 2012-06-20T06:40:04.543 回答
0

您的 Dao 需要标记为@Transactional。

还要注释您的测试:

@TestExecutionListeners(TransactionalTestExecutionListener.class)  //Rolls back transactions by default
于 2012-06-20T06:53:13.150 回答
0
  • 尝试扩展AbstractTransactionalJUnit4SpringContextTests
  • 请注意,MySql MISAM 表不是事务性的,您需要使用 INNODB 类型的表(请参见此处此处
  • 你的 DAO 是否也标有 @Transactional?这可能会导致问题(请参阅此处
于 2012-06-19T15:54:22.773 回答
0

尝试使用 @Transactional 注释测试方法

于 2012-06-19T08:35:01.257 回答
0

还有其他解决方案:

  1. 使用模拟框架(即 Mockito)来模拟数据源。这样你只会测试你的 DAO 逻辑
  2. 使用可以为每个测试设置的单独数据库进行测试。您可以使用 DBUnit 来执行此操作。
  3. 使用内存数据库(即 HSQL),这样更改就不会持续存在。

这样您就不必回滚您的更改。

于 2012-06-15T13:19:10.343 回答
0

请确保您必须声明:

<tx:annotation-driven transaction-manager="transactionManager" /> 

在你的 spring 配置文件中,例如(applicationContext.xml)。

正如@Lieber 已经解释的,但更多解释是:MySQL 服务器(版本 3.23-max 和所有版本 4.0 及更高版本)支持使用 InnoDB 事务存储引擎的事务。InnoDB 提供完全的 ACID 合规性。请参阅第 14 章,存储引擎。有关 InnoDB 在处理事务错误方面与标准 SQL 的差异的信息,请参阅第 14.3.13 节,“InnoDB 错误处理”。

MySQL 服务器中的其他非事务性存储引擎(例如 MyISAM)遵循不同的数据完整性范式,称为“原子操作”。在事务方面,MyISAM 表实际上总是在 autocommit = 1 模式下运行。原子操作通常提供可比的完整性和更高的性能。所以,MyISAM 事务存储引擎总是自动提交事务。

于 2012-06-15T14:08:01.790 回答
0

哈哈,就像三天前一样,我也发生过同样的事情。尝试将 transactionManager ="transactionManager" 添加到您的 @contextConfiguration:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:PersistenceHelper-context.xml"})
@TransactionConfiguration(defaultRollback = true, transactionManager = "transactionManager")
@Transactional

此外,我对此不是 100% 确定,但您的 XML 文件应遵循“*-context”格式。如果您想查看我的 PersistenceHelper-context.xml 文件,请告诉我。

于 2012-06-19T15:23:30.160 回答