简体   繁体   English

Grails /休眠缓存不可预测

[英]Grails/Hibernate Cache unpredictable

I only resort to StackOverflow when I've really tried everything but I just cannot figure out how to solve this problem. 当我真的尝试了所有方法后,我才求助于StackOverflow,但我只是想不出如何解决这个问题。 It is quite easy to replicate, basically I have a table (basically just a key/value table where I keep settings). 复制非常容易,基本上我有一个表(基本上只是保存设置的键/值表)。

class SystemSetting {
    Group settingGroup
    String key
    String value
    String label
    String type

    Date lastUpdated
    Date dateCreated
}

I have a simple controller which allows me to update these settings (@Transactional annotation) and 'flush: true' on the save. 我有一个简单的控制器,可让我更新这些设置(@Transactional批注)并在保存时更新“ flush:true”。

Now, lets say I set an option from true to false (or any change) once this change is made, it is not reflected on other processes/sessions. 现在,可以说,一旦做出更改,我就将选项从true设置为false(或任何更改),它不会反映在其他进程/会话上。

The code to read a setting is the following: 读取设置的代码如下:

SystemSetting setting = SystemSetting.find("FROM SystemSetting ss WHERE ss.settingGroup = :group AND ss.key = :key",
            [group: group, key: key]
        );

So for example, in browser A) I update a setting. 因此,例如,在浏览器A)中,我更新了一个设置。 In browser B (or curl) when I view/access this setting it still has the old value. 在浏览器B(​​或curl)中,当我查看/访问此设置时,它仍然具有旧值。

I have disabled all the caching I know of: 我已禁用所有已知的缓存:

hibernate {
    cache.use_second_level_cache = false
    cache.use_query_cache = false
    cache.region.factory_class = 'org.hibernate.cache.ehcache.EhCacheRegionFactory' // Hibernate 4
    singleSession = true // configure OSIV singleSession mode
    flush.mode = 'manual' // OSIV session flush mode outside of transactional context
}

grails.hibernate.cache.queries = false

But these results are still easily duplicated. 但是这些结果仍然很容易重复。 What/why/where is this option being cached and how to I invalidate it? 什么/为什么/在哪里缓存此选项,以及如何使其无效?

This is really not leaving me with a warm feeling inside as it creates tons of issues if I can't be confident of what data will be coming out of the database :( 确实,这不会让我感到内在的温暖,因为如果我不确定从数据库中将要输出什么数据,则会产生很多问题:(

Using Grails 2.5.1 (and tested on 2.4.4, same result). 使用Grails 2.5.1(并在2.4.4上进行测试,结果相同)。

UPDATE: 更新:

I have been able to duplicate this in a fresh application. 我已经能够在一个全新的应用程序中复制它。

Application is available here: https://github.com/donald-jackson/grails-async-error-demo 可在此处找到应用程序: https : //github.com/donald-jackson/grails-async-error-demo

To duplicate: 复制:

  1. Clone the repository and configure the datasource to use your local MySQL. 克隆存储库并配置数据源以使用本地MySQL。
  2. 'run-app' in Grails and visit /AsyncErrorTest/systemSetting 在Grails中运行“应用程序”并访问/ AsyncErrorTest / systemSetting
  3. Create a setting with optionName = 'testOption' set value to true (or false) 使用optionName ='testOption'将设置值设置为true(或false)来创建设置
  4. Using curl (or other browser) visit /AsyncErrorTest/systemSetting/showVariable a few times, change the variable value and you will see the output correctly reflects the changes. 使用curl(或其他浏览器)几次访问/ AsyncErrorTest / systemSetting / showVariable,更改变量值,您将看到输出正确反映了更改。
  5. Change the value of 'testOption' again. 再次更改“ testOption”的值。
  6. Call /AsyncErrorTest/systemSetting/showVariableAsync a few times using curl and you will notice the variable will start changing its value between the current and previous. 使用curl多次调用/ AsyncErrorTest / systemSetting / showVariableAsync,您会注意到该变量将开始在当前值和上一个值之间更改其值。
  7. Once you notice this behaviour you can check in your browser or even on the original showVariable method and it will also give unreliable output. 注意到此行为后,您可以在浏览器中甚至是原始的showVariable方法中进行检入,它还会提供不可靠的输出。

This was reported to Grails issues and was fixed in Grails 2.5.2. 此问题已报告给Grails问题,并已在Grails 2.5.2中修复。

https://github.com/grails/grails-core/issues/9198 https://github.com/grails/grails-core/issues/9198

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM