1

我试图在我的 creteria 中添加一个悲观锁定,如文档 http://grails.org/doc/latest/guide/GORM.html#locking中所示,但我有一个例外:

“错误 util.JDBCExceptionReporter - 不支持功能:“FOR UPDATE && JOIN”;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{

}

数据源.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 回答