středa 3. června 2009

iBATIS cache is not flushed on transaction rollback

Today, I got several reports of failing test cases from our Teamcity. As usually, I run all the tests locally, but (with no surprise) all passed. So I looked in the build log to figure out what can be wrong and after an hour of digging in and out I found the problem.

In FG, we use AbstractTransactionalDataSourceSpringContextTests to speed-up database tests by running each test case in a separate transaction that is always rolled-back on a test-end. This feature is nice, it speeds database tests greatly and all the test methods are guaranteed to have test data in a consistent state. But when an iBATIS memory cache is in its way, it causes the following problem:

I have a test method that lists entities from database and it removes some of these entities (causing the cache to be cleared). So far, so good, but in the same test method I list entities again. This puts the result to the cache, the deleted entities are not in the result (which is correct for the test method). At the end of the test execution a rollback is issued by the spring. Now, the next test method starts and it also lists entities with the same statement. And here comes the problem - the iBATIS cache is simple (hopefully due to performance problems;) - it doesn't support cache flush on a transaction rollback. So the cache was not flushed, holding less entities than expected and the current test method failed on this assertion.

Because I'm lazy, I used the following workaround in my database abstract test case to force all the caches to be flushed on each test-end.
protected void onTearDownInTransaction() throws Exception {
    // force the iBATIS caches to be cleared (topicCache and postCache)
    this.forumStorage.deleteTopic(-1);
}

Well, it's time to pay more attention to this issue: iBATIS cache transaction rollback

Žádné komentáře:

Okomentovat