我试图在我的标准中添加悲观锁定,如文档所示
http://grails.org/doc/latest/guide/GORM.html#locking但我有一个异常(exception):
“错误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{
}
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"
}
}
}
}
最佳答案
根据您形成查询的方式,Hibernate将执行不同的查询。查询的编写方式Hibernate将执行联接-这可能对性能有好处,因为这意味着已在1查询中预提取了联接的实体。但是,这对于锁定很不利,因为每个联接的表都必须被锁定,并且这可能会对深度层次产生很大影响。因此,您的数据库不允许这样做(我什至不确定是否还有其他允许)。
您将必须在没有联接的情况下执行查询。根据您的域类实现,可以在不接触数据库的情况下完成一个简单的Child.parent.id
,然后您的查询将变成一个简单的Parent.lock(Child.parent.id)
。看不到实际的域类很难说。
您始终可以做的是在非锁定查询中获取Parent
,然后在返回的实例上调用lock()
方法。我建议您看一下有关锁定GORM中内容的出色article,以获取更多信息。
关于hibernate - grails/hibernate:在使用条件上添加悲观锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27015731/