2013-05-02 130 views
3

我有一个服务,我想缓存。我一直在寻找grails-cache plugin,它看起来非常有前途,但它造成了一些我不明白的行为。为什么打开@Cacheable会导致我的事务失败?

考虑以下服务:

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:012因为它已被标记为只回滚

我什么混淆了最大约这是与@Cacheable注释的方法不是由我FooService甚至称事务回滚。只调用evaluate()方法,并且该方法似乎没有问题。为什么要将这个注解添加到一个甚至没有在这个执行中使用的方法会导致事务回滚?

+0

你看到用'grails.cache.proxyTargetClass'配置选项设置相同的行为到'真的'? – 2013-05-02 23:06:49

+0

@Andrew:是的,与此设置相同的行为。 – Samo 2013-05-03 13:13:20

+0

@Samo你有没有找到这种行为的原因? – Thihara 2015-01-01 09:57:26

回答

0

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

static transactional = false 
相关问题