【问题标题】:org.hibernate.StaleObjectStateException when using Grails with PostgreSQL将 Grails 与 PostgreSQL 一起使用时出现 org.hibernate.StaleObjectStateException
【发布时间】:2010-11-25 13:59:05
【问题描述】:

我用以下代码编写了一个 grails 服务:

EPCGenerationMetadata requestEPCs(String indicatorDigit, FilterValue filterValue,     
    PartitionValue partitionValue, String companyPrefix, String itemReference, 
    Long quantity) throws IllegalArgumentException, IllegalStateException {  

    //... code
    //problematic snippet bellow
    def serialGenerator
    synchronized(this) {
        log.debug "Generating epcs..."
        serialGenerator = SerialGenerator.findByItemReference(itemReference)
        if(!serialGenerator) {
            serialGenerator = new SerialGenerator(itemReference: itemReference, serialNumber: 0l)
        }
        startingPoint = serialGenerator.serialNumber + 1
        serialGenerator.serialNumber += quantity
        serialGenerator.save(flush: true)
    }
    //code continues...
}

作为一个 grails 服务,默认情况下是单例,我认为通过添加上面的同步块可以避免并发不一致。我创建了一个简单的客户端来测试并发性,因为服务是由 http 调用程序公开的。我同时运行多个客户端,将相同的 itemReference 作为参数传递,并且完全没有问题。

但是,当我将数据库从 MySQL 更改为 PostgreSQL 8.4 时,我无法再处理并发访问了。运行单个客户端时,一切都很好。但是,如果我再添加一个请求相同 itemReference 的客户端,我会立即收到 StaleObjectStateException:

线程“主”org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException 中的异常:标识符为 [10] 的类 [br.com.app.epcserver.SerialGenerator] 的对象:乐观锁定失败;嵌套异常是 org.hibernate.StaleObjectStateException:行已被另一个事务更新或删除(或未保存值映射不正确):[br.com.app.epcserver.SerialGenerator#10] 在 org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:672) 在 org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412) 在 org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411) 在 org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374) 在 org.springframework.orm.hibernate3.HibernateTemplate.flush(HibernateTemplate.java:881) 在 org.codehaus.groovy.grails.orm.hibernate.metaclass.SavePersistentMethod$1.doInHibernate(SavePersistentMethod.java:58) (...) 在 br.com.app.EPCGeneratorService.requestEPCs(EPCGeneratorService.groovy:63) 在 br.com.app.epcclient.IEPCGenerator$requestEPCs.callCurrent(未知来源) 在 br.com.app.epcserver.EPCGeneratorService.requestEPCs(EPCGeneratorService.groovy:29) 在 br.com.app.epcserver.EPCGeneratorService$$FastClassByCGLIB$$15a2adc2.invoke() (...) 原因:org.hibernate.StaleObjectStateException:行被另一个事务更新或删除(或未保存的值映射不正确):[br.com.app.epcserver.SerialGenerator#10]

注意:EPCGeneratorService.groovy:63 指的是serialGenerator.save(flush: true)。

我不知道该怎么想,因为我唯一改变的是数据库。我将不胜感激有关此事的任何建议。

我正在使用:
Grails 1.3.3
Postgres 8.4(postgresql-8.4-702.jdbc4 驱动程序)
JBoss 6.0.0-M4

MySQL:
mysqld Ver 5.1.41 (mysql-connector-java-5.1.13-bin 驱动)

提前致谢!

【问题讨论】:

    标签: mysql hibernate spring postgresql grails


    【解决方案1】:

    这很奇怪,请尝试禁用事务。

    【讨论】:

      【解决方案2】:

      这确实是一种奇怪的行为,但您可以尝试通过休眠锁定方法使用“select ... for upgrade”来解决问题。

      类似这样的:

      def c = SerialGenerator.createCriteria()
      serialgenerator = c.get {
        eg "itemReferece", itemReference
        lock true
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-04
        • 2019-08-28
        • 1970-01-01
        • 2021-02-28
        • 2017-10-19
        相关资源
        最近更新 更多