使用以下代码,任何人都可以轻松地在单个线程中获得数据库死锁:只需使用悲观的LockMode在嵌套事务中选择一个对象两次。
def deadlockWithinSingleThread() {
long id = ...
Dog.withNewTransaction {
getIt(id)
Dog.withNewTransaction {
getIt(id)
}
}
}
private Dog getIt(long id) {
Dog.withCriteria(uniqueResult: true) {
idEq id
lockMode LockMode.PESSIMISTIC_WRITE
maxResults 1
}
}
有没有办法检测出这种简单的死锁?或者,我是否可以(通过请求)知道对象是否已被同一个线程锁定?
就我个人而言,我更喜欢第二个get()
失败并出现例外情况。例如,我认为检测Spring的这种情况并不是一个很大的伎俩。然而,即使没有警告。
Grails 2.2.0,PostgreSQL 9,Spring,Hibernate 3.2