Pom*_*rio 2 spring transactions
我正在尝试编写一段代码,在其中我可以看到在RuntimeException上回滚的@Transaction方法.这应该是预期的默认行为,但它不是我所看到的.有什么想法吗?
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:mrpomario/springcore/jdbc/jdbc-testenv-config.xml")
@Transactional // Will rollback test transactions at the end
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class TransactionalTest
{
@Autowired
FeedManagerOne feedManagerOne;
@Test
public void test_RuntimeExceptions_Rollback_Behaviour(){
Feed bogus = new Feed("B", "B", false);
assertFalse(feedManagerOne.exists(bogus));
try {
feedManagerOne.createFeedAndThrowRuntimeException(bogus);
} catch (RuntimeException e) { }
// WRONG! feedManagerOne.exists(bogus) SHOULD return false, but returns true.
assertFalse(feedManagerOne.exists(bogus));
}
}
Run Code Online (Sandbox Code Playgroud)
我的服务:
@Service
public class FeedManagerOne {
@Autowired
JdbcTemplate jdbcTemplate;
@Transactional(readOnly = true)
public boolean exists(Feed feed) {
String query = "SELECT COUNT(*) FROM feed WHERE name = ? AND url = ? AND is_active = ?";
int total = jdbcTemplate.queryForInt(query, feed.getName(), feed.getUrl(), feed.isActive());
boolean found = (total == 1);
return found;
}
@Transactional
public boolean createFeedAndThrowRuntimeException(Feed feed) {
String query = "INSERT INTO feed (name, url, is_active) values (?, ?, ?)";
int rowsChanged = jdbcTemplate.update(query, feed.getName(), feed.getUrl(), feed.isActive());
boolean created = (rowsChanged == 1);
if (true)
{
throw new RuntimeException();
}
return created;
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我定义TransactionManager的方式:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="mrpomario/springcore/jdbc/testdb/schema.sql"/>
<jdbc:script location="classpath:mrpomario/springcore/jdbc/testdb/test-data.sql"/>
</jdbc:embedded-database>
Run Code Online (Sandbox Code Playgroud)
这是预期的行为.
当您从@Transactional方法抛出异常(应该导致回滚)时,Spring会将transcation标记为在其末尾回滚.因此,如果从@Transactional调用堆栈中的最顶层方法抛出异常,则事务将立即回滚.
但在您的情况下,您的测试方法也是@Transactional如此,因此您只有一个跨越整个测试方法的事务.这意味着尽管事务在调用后被标记为回滚createFeedAndThrowRuntimeException(),但它在测试方法结束之前不会回滚,因此第二次调用exists()可以观察到更改.
因此,如果要查看回滚,则需要使测试方法成为非事务性的.
我也没有<tx:annotation-driven/>在你的配置中看到.
| 归档时间: |
|
| 查看次数: |
2436 次 |
| 最近记录: |