【问题标题】:Page Refresh(F5) changes the data on the screen after successful save in db in Grails app页面刷新(F5)在Grails应用程序中成功保存到db后更改屏幕上的数据
【发布时间】:2011-03-24 15:49:12
【问题描述】:

我为遗留数据库开发了一个 grails/groovy 应用程序,该数据库具有用于(添加、编辑)用户信息的用户维护页面。该页面正在使用 editinplace 和 ajax 来更新信息。

该程序已在本地测试,没有问题。但是,在任何远程服务器(alpha、beta、prod)上,当我“更新”用户的任何属性时,它会将其保存在数据库中,但是当我刷新页面时,内容“有时”会返回以前的值。如果我一直按刷新 (F5),它将在新旧值之间切换而没有任何特定趋势。 (无法在本地重现)

我认为这可能是缓存问题,所以我在用户域上将缓存设置为 false

class User {
static hasMany = [notes: Note]
static mapping = {
    table 'MICR_USERS'  
    cache false
    version false        
    id generator:'sequence', column:'SEQ_ID', params:[sequence:'MICR_USR']
    lineOfBusiness column:'LOB_APP_CODE'
    authorityProfile column:'AUTH_PRIVILEGE_LEVEL', lazy:false
}
...

我认为可能导致问题的另一件事是列表操作中的 createCriteria,我也将缓存设置为 false

    def list = {
    def f = getUserList(session.oldSearchUserTextBox?:null)
    return [list:f,oldSearchKeyword:session.oldSearchUserTextBox]
}

    private getUserList(String searchFilter){
            ....
    def c = User.createCriteria()
    def results
    if (searchFilter) {
        results = c.list (max: params.max, offset: params.offset) {
            or {
                ilike ("oraAcct", "%"+ searchFilter+"%" )
                ilike ("lastName", "%"+ searchFilter+"%" )
                ilike ("firstName", "%"+ searchFilter+"%" )
            }
            order("oraAcct", "asc")
            cache false
        }
    }
    else {
        results = c.list (max: params.max, offset: params.offset) {
            cache false
            order("oraAcct", "asc")
        }
    }
    [userInstanceList : results,userInstanceTotal :results.getTotalCount()]
}

这是我的保存方法

    private JSON saveValidateObj(def myUser,def oldValue,def fieldname,def returnFieldName){
    try {
        def value =  myUser."$fieldname"
        if( myUser.validate() && myUser.save(flush:true) ) {
            if (returnFieldName) value = value."$returnFieldName"
            flashMessage = getMess('user.information.update.success',[
                myUser.oraAcct,
                oldValue,
                value
            ])

            def json = ['value':value,'id':params.id,'updatedField': fieldname,'errorList':null,'errMessage':null,'okMessage':flashMessage]
            def j = json as JSON
            return j
        }

.....

似乎休眠状态保留了不同版本的数据,并且通过随机刷新页面,将显示其中一个版本。然而,最新的值占主导地位并且出现得更频繁,但仍然看到旧值出现在屏幕上是毁灭性的。

这些是我做过但没有帮助的步骤 1-关闭缓存(检查休眠统计信息以确保其关闭) cache.use_second_level_cache=false cache.use_query_cache=false

2- 在不同的浏览器中尝试过

3- 清理浏览器缓存并删除co​​okies

我也怀疑 websphere 是我的生产服务器,我的本地是 apache,但真的不知道为什么它会这样反应

Grails/休眠 1.1

我仍然有这个问题,想不出别的。我很感激,如果有人可以给我任何提示

新发现

如果我使用select u.id, u.sysAcct, u.firstName, u.lastName, u.mailAddress, u.phoneExt from User u... ,问题将得到解决。但如果我使用select u from User u,... 问题将再次发生。出于某种原因,如果我返回 User 对象,则会发生此问题。 getUserListHSQLStatic 和 getUserListHSQL 基本相同,只是一个是返回对象,一个是返回字段。静态值永远不会通过按 F5 改变,但对象(用户)会改变。

    private getUserListHSQLStatic(params){
    def filter = params.filter
    def newlist
    def count
    def query = """
        select      
        u.id, u.sysAcct, u.firstName, u.lastName, u.mailAddress, u.phoneExt
        ,lob.name,auth.name
        from User u, AuthorityProfile auth, LineOfBusiness lob
        where  u.authorityProfile = auth.id
        and  u.lineOfBusiness = lob.id
        and u.sysAcct not like '%DUMMY%'
        """
    if (filter){
        query +="""
         and (u.sysAcct  like :filter or
             u.sysAcct  like :lfilter or
             u.firstName like :filter or
             u.firstName like :lfilter or
             u.lastName  like :filter or
             u.lastName  like :lfilter
        ) order by u.sysAcct asc
        """
        def filterMap =  [filter:"%${filter.toUpperCase()}%",lfilter:"%${filter.toLowerCase()}%"]
        newlist = User.executeQuery(query,filterMap,
                [ max:params?.max?.toInteger()?:10, offset:params?.offset?.toInteger()?:0]
                )
        count = User.executeQuery(query,filterMap).size()
    }
    else {
        query += " order by u.sysAcct asc "
        newlist = User.executeQuery(query,[max:params?.max?.toInteger()?:10, offset:params?.offset?.toInteger()?:0])
        count = User.executeQuery(query).size()
    }
    [userInstanceList:newlist,userInstanceTotal:count]
}
private getUserListHSQL(params){
    def mysession = sessionFactory.currentSession
    if (params.reset=="true"){
        println "clear session"
        mysession.clear()
    }

    def filter = params.filter
    def newlist
    def count
    def query = """
        select u
        from User u, AuthorityProfile auth, LineOfBusiness lob
        where  u.authorityProfile = auth.id
        and  u.lineOfBusiness = lob.id
        and u.sysAcct not like '%DUMMY%'
        """
    if (filter){
        query +="""
         and (u.sysAcct  like :filter or
             u.sysAcct  like :lfilter or
             u.firstName like :filter or
             u.firstName like :lfilter or
             u.lastName  like :filter or
             u.lastName  like :lfilter
        ) order by u.sysAcct asc
        """
        def filterMap =  [filter:"%${filter.toUpperCase()}%",lfilter:"%${filter.toLowerCase()}%"]
        newlist = User.executeQuery(query,filterMap,
                [ max:params?.max?.toInteger()?:10, offset:params?.offset?.toInteger()?:0]
                )
        count = User.executeQuery(query,filterMap).size()
    }
    else {
        query += " order by u.sysAcct asc "
        newlist = User.executeQuery(query,[max:params?.max?.toInteger()?:10, offset:params?.offset?.toInteger()?:0])
        count = User.executeQuery(query).size()
    }
    [userInstanceList:newlist,userInstanceTotal:count]
}

【问题讨论】:

  • 你不是创建了两次然后从结果集中获取第一个值吗?顺序将是任意的,特别是如果这是一个生产数据库,而不是一些 HSQLDB 玩具数据库。
  • @julkiewicz,我不确定我是否遵循您所说的“创建两次然后获得第一个值”的意思。我只是用新值更新用户对象并将其保存到数据库。在列表操作中,我只是获取所有列表或过滤它(如果过滤器存在)。此代码现在正在生产中,并带有此错误。它正在使用 oracle 数据库。
  • 您能否确认您的数据库中绝对没有 2 个同名用户(我认为这是 @julkiewicz 所要求的)。我怀疑是这种情况,您可能在 DB 中拥有独一无二的名称...
  • @Chris,oraAcct 是系统中存在的唯一用户标识。但是,用户通过 seq_id (id) 进行区分,并且该列上有唯一的约束。我有点倾向于关于休眠缓存的想法。但是,打开/关闭缓存标志不会有任何好处(我可能做得不对)。该代码在开发环境(本地)中完美运行,这使得调试变得更加困难。

标签: grails grails-domain-class


【解决方案1】:

其他环境中是否有多个服务器?另外,当您刷新时,使用 Firebug 之类的工具可以检查响应代码不是 304 吗?最后,当你说你清除了浏览器缓存时,你是不是在清除缓存后得到的是旧值?

由于您使用的是“就地编辑”,因此您要检索的页面通常会被浏览器缓存(如果您使用的是 Chrome,我发现它这样做几乎过于激进)。我想确保服务器通过网络传回旧数据。

【讨论】:

  • 我建议安装此插件以确保您的响应也不会被缓存grails.org/plugin/cache-headers
  • 感谢您的回复。我查看了您提到的那些项目,状态码是 200。我使用了 IE 调试器并清除了缓存并检查了从服务器选项读取,但仍然遇到同样的问题。在您提到的插件上,该插件适用于 grails 1.2.0 > *,我们使用的是 1.1。
  • 我在会话中添加了一个计数器变量,并在我点击控制器操作时增加它。我看起来一直都在打击控制器。
【解决方案2】:

此时问题仍然未知,但是,我能够通过使用

def query = """ select  u.id, u.sysAcct, u.firstName, u.lastName, u.mailAddress, ...

而不是返回整个对象。

def query = """ select u from User u, AuthorityProfile auth, LineOfBusiness lob   ...

此更改解决了我的问题,刷新页面不会再更改值。

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 2017-02-27
    • 2016-10-09
    • 2017-11-05
    相关资源
    最近更新 更多