为什么启用@Cacheable会导致我的事务失败?

时间:2013-05-02 19:57:18

标签: caching grails rollback spring-transactions

我有一项服务,我希望可以缓存。我一直在调查grails-cache plugin,它看起来非常有前景,但它引起了一些我不理解的行为。

考虑以下服务:

class FooService {
    def contentService

    @Listener
    void processFoo(Foo foo) {
        doStuff(foo)
        foo.save(failOnError: true)
    }

    private void doStuff(Foo foo) {
        contentService.evaluate(foo.name)
    }
}

现在这里是ContentService定义:

class ContentService {
    Object findSource(String name) {
        Content.findByPath(name) ?: Content.findByPath(stripLocale(name))
    }

    String evaluate(String name) {
        ....
    }
}

这一切都正常,直到我尝试添加缓存。首先,我在Config.groovy中设置它:

grails.cache.config = {
    cache {
        name 'content'
    }
}

然后在我的ContentService中,我注释了我的方法:

@Cacheable('content')
Object findSource(String name) {
    Content.findByPath(name) ?: Content.findByPath(stripLocale(name))
}

进行这些更改后,我的processFoo方法成功执行了每行代码,然后在退出时抛出其中一个:

  

非法arg invokation java.lang.reflect.InvocationTargetException   org.springframework.transaction.UnexpectedRollbackException:   事务已回滚,因为它已标记为仅回滚

最让我困惑的是,带@Cacheable注释的方法甚至不被我的FooService调用。仅调用evaluate()方法,并且该方法似乎没有问题。为什么将此注释添加到甚至不在此执行中使用的方法会导致事务回滚?

1 个答案:

答案 0 :(得分:0)

你的FooService和ContentService真的需要在交易中表现吗?如果没有,请尝试通过将以下行添加到服务类中来禁用服务的事务行为,并查看它是否有帮助:

static transactional = false