org.hibernate.StaleObjectStateException при использовании Grails с PostgreSQL - PullRequest
2 голосов
/ 25 ноября 2010

Я написал сервис 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 invoker. Я запускал несколько клиентов одновременно, передавая в качестве аргумента один и тот же itemReference, и у меня не было проблем вообще.

Однако, когда я изменил базу данных с MySQL на PostgreSQL 8.4, я больше не мог обрабатывать параллельный доступ. При запуске одного клиента все нормально. Однако, если я добавлю еще одного клиента, запрашивающего тот же itemReference, я сразу получу StaleObjectStateException:

Exception in thread "main" org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Object of class [br.com.app.epcserver.SerialGenerator] with identifier [10]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [br.com.app.epcserver.SerialGenerator#10]  
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:672)  
    at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)  
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)  
    at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)  
    at org.springframework.orm.hibernate3.HibernateTemplate.flush(HibernateTemplate.java:881)  
    at org.codehaus.groovy.grails.orm.hibernate.metaclass.SavePersistentMethod$1.doInHibernate(SavePersistentMethod.java:58)  
    (...)  
    at br.com.app.EPCGeneratorService.requestEPCs(EPCGeneratorService.groovy:63)  
    at br.com.app.epcclient.IEPCGenerator$requestEPCs.callCurrent(Unknown Source)  
    at br.com.app.epcserver.EPCGeneratorService.requestEPCs(EPCGeneratorService.groovy:29)  
    at br.com.app.epcserver.EPCGeneratorService$$FastClassByCGLIB$$15a2adc2.invoke()  
        (...)  
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [br.com.app.epcserver.SerialGenerator#10]

Примечание: EPCGeneratorService.groovy: 63 относится к serialGenerator.save (flush: true).

Я не знаю, что и думать, поскольку единственное, что я изменил, - это база данных. Буду признателен за любые советы по этому вопросу.

Я использую:
Грааль 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)

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 26 ноября 2010

Это странно, попробуйте отключить транзакцию.

0 голосов
/ 25 июля 2014

Это действительно странное поведение, но вы можете попытаться обойти его, используя «выбрать ... для обновления», с помощью метода блокировки гибернации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...