我试图在我的creteria中添加悲观锁定,如文档中所示 http://grails.org/doc/latest/guide/GORM.html#locking但我有一个例外:
" ERROR util.JDBCExceptionReporter - 功能不受支持:" FOR UPDATE&& JOIN&#34 ;; 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 :(得分:3)
根据您构建查询的方式,Hibernate将执行不同的查询。编写查询的方式Hibernate将执行连接 - 这可能对性能有利,因为这意味着已经在1查询中预先获取了已连接的实体。但是对于锁定而言这很糟糕,因为每个连接的表都必须被锁定,这对深度层次结构会产生很大的影响。因此,您的数据库不允许它(我甚至不确定是否有其他人)。
您必须在不加入的情况下执行查询。根据您的域类实现,可以在不触及数据库的情况下完成简单的Child.parent.id
,然后您的查询变为简单的Parent.lock(Child.parent.id)
。没有看到实际的域类,很难说。
您可以随时执行的操作是在非锁定查询中获取Parent
,然后在返回的实例上调用lock()
方法。我建议你看看这个关于GORM锁定事物的优秀article以获取更多信息。