1

ドキュメントhttp://grails.org/doc/latest/guide/GORM.html#lockingに示されているように、クレテリアに悲観的ロックを追加しようとしました が、例外がありました:

「エラー util.JDBCExceptionReporter - 機能がサポートされていません: "FOR UPDATE && JOIN"; SQL ステートメント: ... org.hibernate.exception.GenericJDBCException: クエリを実行できませんでした」

次の 2 か所にロックを追加しようとしました。

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{

}

データソース.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"
                    }
                }
            }
        }
4

1 に答える 1

3

クエリの作成方法に応じて、Hibernate はさまざまなクエリを実行します。クエリの記述方法 Hibernate は結合を実行します。これは、結合されたエンティティが 1 つのクエリで既にプリフェッチされることを意味するため、パフォーマンスが向上する可能性があります。ただし、ロックの場合、結合されたすべてのテーブルをロックする必要があり、これは深い階層に大きな影響を与える可能性があるため、これは悪いことです。したがって、あなたのデータベースはそれを許可していません(他のデータベースが許可しているかどうかさえわかりません)。

結合なしでクエリを実行する必要があります。ドメインクラスの実装によってはChild.parent.id、データベースに触れずに簡単に実行でき、クエリが簡単になりますParent.lock(Child.parent.id)。実際のドメイン クラスを確認しないと何とも言えません。

いつでもできることはParent、非ロック クエリで を取得lock()し、返されたインスタンスでメソッドを呼び出すことです。詳細については、GORM でのロックに関するこの優れた記事をご覧になることをお勧めします。

于 2014-11-19T12:48:58.027 に答える