How to roll back a test

Here is my test:

@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); } 

and dataSource in the bean configuration file

 <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" /> 

When I run this test, a new record is created in my database.

How can I cancel this transaction?

This is the output of the log I see:

 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]]] 

UPDATE:

all the answers below want to change the logic or mechanism of the database, which I don't want. Therefore, I offer a reputation for the correct answer:

Why, when I have this: @TransactionConfiguration(defaultRollback = true) in the transaction configuration tests do not roll back and how can I fix it?

+4
source share
9 answers

If you are using MySQL with the MyISAM engine, try switching to InnoDB.

For a more sophisticated test, you probably need a mocking infrastructure or rest in the database.

EDIT1: According to the documentation, InnoDB is broadcast with full ACID support, while MyISAM supports atomic operations. More reading: Differences in transactional and atomic operations

EDIT2: In @TransactionConfiguration, the default value for defaultRollback is true, so instead of commenting out the line, you should add @TransactionConfiguration (defaultRollback = false)

+7
source

At first glance, your code and configuration look right. However, could you please place your SeasonsDAO facility. First we need to make sure that SeasonsDAO is properly configured for transactions.

SeasonsDAO must participate in the same TransactionContext as your test case, and there is no way to verify that with the code you published.

Did you mark SeasonsDAO as @Transactional?

If this is not the case, I'm not sure how TransactionProxyFactoryBean will be able to proxy and declaratively manage the transaction.

At a high level, spring uses the concept of proxy to perform many services, such as transaction management.

If you mark something like @Transactional, spring will dynamically create a proxy server that will implement the same interfaces as your target class. After it is proxied, the transaction interceptor will transfer the method calls to your target class and decide whether to roll back or commit transactions based on the standards or rules that you can specify.

+1
source

There are other solutions for this:

  • Use a fake framework (i.e. Mockito) to make fun of a data source. That way, you only check your DAO logic.
  • Use a separate test database that can be configured for each test. You can use DBUnit for this.
  • Use a database in memory (i.e. HSQL), so changes will not be saved.

This way you do not have to roll back your changes.

0
source

Please make sure you need to declare:

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

in the spring configuration file, for example. (ApplicationContext.xml).

As @Lieber already explained, but more is explained: MySQL Server (version 3.23-max and all versions 4.0 and higher) supports transactions with the InnoDB transactional storage mechanism. InnoDB provides full ACID compliance. See Chapter 14, Storage Engines. For information on differences between InnoDB and standard SQL with respect to transactional error handling, see Section 14.3.13, InnoDB Error Handling.

Other non-transactional storage systems in MySQL Server (such as MyISAM) follow a different paradigm for data integrity called atomic operations. In transactional conditions, MyISAM tables work effectively in autocommit = 1 mode. Atomic operations often provide comparable integrity and high performance. Thus, the MyISAM transactional storage engine always performs an autocommit transaction.

0
source

try annotating the test method with @Transactional

0
source

Haha, the same thing happened to me as 3 days ago. Try adding transactionManager = "transactionManager" to @contextConfiguration:

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

In addition, I am not 100% sure, but your XML file must conform to the "* context" format. Let me know if you want to see my PersistenceHelper-context.xml file.

0
source
  • Try expanding AbstractTransactionalJUnit4SpringContextTests
  • Please note: MySql MYISAM tables are not transactional, you need to use tables like INNODB (see here and here )
  • Is your DAO also tagged @Transactional? This may cause a problem (see here )
0
source

Try using the following method after the test logic.

 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 
0
source

Your Dao should be @Transactional marked.

Also annotate your test with:

 @TestExecutionListeners(TransactionalTestExecutionListener.class) //Rolls back transactions by default 
0
source

All Articles