这是我的测试:
@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)
没有回滚以及如何修复它?
答案 0 :(得分:7)
如果您使用MySQL和MyISAM引擎,请尝试切换到InnoDB。
对于更复杂的测试,您可能需要一个模拟框架或DB娱乐。
EDIT1: 根据文档,InnoDB是完全ACID支持的事务,而MyISAM支持原子操作。更多阅读:Transaction and Atomic Operation Differences
EDIT2: 在@TransactionConfiguration中,defaultRollback的默认值为true,因此您应该添加@TransactionConfiguration(defaultRollback = false)而不是注释该行
答案 1 :(得分:1)
从表面上看,您的代码和配置看起来是正确的。但是,您可以发布您的SeasonsDAO对象吗?我们首先需要验证SeasonsDAO是否正确配置了交易。
SeasonsDAO需要参与与您的测试用例相同的TransactionContext,并且无法使用您发布的代码进行验证。
您是否将SeasonsDAO标记为@Transactional?
如果不是,我不确定TransactionProxyFactoryBean如何能够代理和声明性地管理事务。
在较高的层面上,spring使用代理的概念来执行许多服务,例如事务管理。
如果您将某些内容标记为@Transactional,Spring将动态创建一个代理,该代理将实现与目标类相同的接口。代理之后,事务拦截器会将方法调用包装到目标类,并根据您指定的默认值或规则决定是回滚还是提交。
答案 2 :(得分:0)
还有其他解决方案:
这样您就不必回滚更改了。
答案 3 :(得分:0)
请确保您必须声明:
<tx:annotation-driven transaction-manager="transactionManager" />
你的弹簧配置文件中的,例如(applicationContext.xml中)。
正如@Lieber已经解释过但更多的解释是:MySQL Server(版本3.23-max和所有版本4.0及更高版本)支持与InnoDB事务存储引擎的事务。 InnoDB提供完整的ACID合规性。请参见第14章,存储引擎。有关InnoDB与标准SQL在处理事务错误方面的差异的信息,请参见第14.3.13节“InnoDB错误处理”。
MySQL服务器中的其他非事务性存储引擎(例如MyISAM)遵循称为“原子操作”的数据完整性的不同范例。在事务方面,MyISAM表实际上始终以autocommit = 1模式运行。原子操作通常提供相当的完整性和更高的性能。因此,MyISAM事务存储引擎始终自动提交事务。
答案 4 :(得分:0)
尝试使用@Transactional
注释测试方法答案 5 :(得分:0)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:PersistenceHelper-context.xml"})
@TransactionConfiguration(defaultRollback = true, transactionManager = "transactionManager")
@Transactional
另外,我对此并非100%肯定,但您的XML文件应遵循&#34; * - context&#34;格式。如果您想查看我的PersistenceHelper-context.xml文件,请告诉我。
答案 6 :(得分:0)
答案 7 :(得分:0)
在测试用例逻辑之后尝试使用以下方法。
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
答案 8 :(得分:0)
您的Dao需要标记为@Transactional。
还用以下内容注释您的测试:
@TestExecutionListeners(TransactionalTestExecutionListener.class) //Rolls back transactions by default