2014-11-19 2 views
1

Я пытался добавить пессимистическую блокировку в моем creteria, как это показано в доке http://grails.org/doc/latest/guide/GORM.html#locking, но у меня было исключение:Grails/Спящий режим: добавить пессимистическую блокировку на использование creteria

«ERROR util.JDBCExceptionReporter - функция не поддерживается : "FOR UPDATE & & РЕГИСТРИРУЙТЕСЬ"; заявление SQL: ... org.hibernate.exception.GenericJDBCException: не удалось выполнить запрос»

Я пытался добавить замок в двух местах:

def ParentInstance = Parent.createCriteria().get { 
    Childs { 
      idEq(ChildInstance.id) 
      lock true 
    } 

И

def ParentInstance = Parent.createCriteria().get { 
    Childs { 
      idEq(ChildInstance.id)  
    } 
    lock true    
} 

Дополнительный вопрос: Является ли это правильный способ использовать пессимистическую блокировку ассоциации?

Спасибо

домена

class Parent{ 
    static hasMany = [Childs:Child]  
} 

class Child{ 

} 

DataSource.groovy

 dataSource { 
      pooled = true 
      driverClassName = "org.h2.Driver" 
      username = "sa" 
      password = "" 
     } 
     hibernate { 
      cache.use_second_level_cache = true 
      cache.use_query_cache = false 
      cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory' 
     } 
     // environment specific settings 
     environments { 
      development { 
       dataSource { 
        dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', '' 
        url = "jdbc:h2:myApp_prodDb;MVCC=TRUE" 
       } 
      } 
      test { 
       dataSource { 
        dbCreate = "update" 
        url = "jdbc:h2:mem:myApp_testDb;MVCC=TRUE" 
       } 
      } 
      production { 
       dataSource { 
        dbCreate = "update" 
        url = "jdbc:h2:myApp_prodDb;MVCC=TRUE" 
        pooled = true 
        properties { 
         maxActive = -1 
         minEvictableIdleTimeMillis=1800000 
         timeBetweenEvictionRunsMillis=1800000 
         numTestsPerEvictionRun=3 
         testOnBorrow=true 
         testWhileIdle=true 
         testOnReturn=true 
         validationQuery="SELECT 1" 
        } 
       } 
      } 
     } 
+0

В какой базе данных у вас есть? –

+0

Я использую базу спящего режима – Jils

+0

Спящий режим - это всего лишь слой между вашим приложением и базой данных. Эта база данных может быть H2 (база данных in-mem предоставлена ​​Grails), PostgreSQL, SQL Server, Oracle, MySql ... Можете ли вы перечислить содержимое вашего файла DataSource.groovy (обязательно удалите любую личную информацию, такую ​​как IP-адреса и пароли, однако)? –

ответ

3

В зависимости от того, как вы формируете запрос, Hibernate будет выполнять различные запросы. То, как написан ваш запрос, Hibernate будет выполнять соединение - это может быть полезно для производительности, потому что это означает, что ваши объединенные объекты уже будут предварительно заданы в 1 запросе. Однако для блокировки это плохо, так как каждая объединенная таблица должна быть заблокирована, и это может иметь большое влияние на глубокие иерархии. Таким образом, ваша база данных не позволяет это (я даже не уверен, что это делает другой).

Вам нужно будет выполнить свой запрос без соединений. В зависимости от реализации класса домена простой Child.parent.id можно было бы сделать, не касаясь базы данных, а затем ваш запрос станет простым Parent.lock(Child.parent.id). Трудно сказать, не видя реальных классов домена.

Что вы всегда можете сделать, это получить Parent в неблокирующем запросе, а затем вызвать метод lock() для возвращаемого экземпляра. Я бы предложил вам взглянуть на этот отличный article на блокировку вещей в GORM для получения дополнительной информации.

+0

Я не использовал метод statis 'ownTo', поэтому не может напрямую получить родителя от ребенка? – Jils

+0

Я добавил классы домена – Jils

+1

Вы можете добавить 'static belongsTo = [родительский: родительский]' в свой класс 'Child' и получить доступ к родительскому элементу через' child.parent' (который вы бы затем «lock()») или 'Parent.lock (child.parent.id)' (см. разницу между двумя в связанной статье, но более поздняя форма, вероятно, лучше). Вы должны знать, что это изменит схему, которую создает GORM - с вашей текущей настройкой, она создает таблицу сопоставления (вероятно, называемую «parent_child»), и с измененной настройкой она просто включает столбец 'parent_id' в' вместо этого. –

Смежные вопросы