参考文章:
http://blog.csdn.net/aesop_wubo/article/details/8286215
http://www.aichengxu.com/view/24054
最近碰到在领域类中自关联时产生的死锁问题,被困扰了好几天,
后面解决时发现太简单了,真是始料不及呀。。。
// 我碰到死锁时,领域类的关键代码如下,翻开数据库day表发现自关联时生成的列为:parent_id
class Day {
String name
static belongsTo = [parent: Day]
static hasMany = [children: Day]
}
// 操作Day的服务代码简化如下
@Transactional
class DayService {
// 注意:saveDay方法会被多条线程同时调用,
// 参数day都是在各个线程中自己New出来的,
// 所以参数day是线程安全的
saveDay(def day){
// 该行代码在被多条线程同时调用时,有可能会获取到同一个dayParent
// 这里就需要注意了,有可能多条线程同时操作数据库中的同一行记录
def dayParent = getParent(day.name)
// 就是下面这行代码产生了:Deadlock found when trying to get lock; try restarting transaction
// 原因:多条线程同时操作数据库中的同一行记录,在相互等待时产生了死锁
dayParent.addToChildren(dayParent)
}
Day getParent(String name) {
def day = Day.where {
name == name
}.get()
return day
}
}
------------------------------------------------------------------
解决方法:
// 注意:saveDay方法会被多条线程同时调用,
// 参数day都是在各个线程中自己New出来的,
// 所以参数day是线程安全的
saveDay(def day){
// 该行代码在被多条线程同时调用时,有可能会获取到同一个dayParent
// 这里就需要注意了,有可能多条线程同时操作数据库中的同一行记录
def dayParent = getParent(day.name)
//dayParent.addToChildren(dayParent) // 注释掉该行代码
day.parent = dayParent // day都是线程安全的,这样写也可以达到类自相关的目的,而且还很可靠,何乐而不为呢。。。
http://blog.csdn.net/aesop_wubo/article/details/8286215
http://www.aichengxu.com/view/24054
最近碰到在领域类中自关联时产生的死锁问题,被困扰了好几天,
后面解决时发现太简单了,真是始料不及呀。。。
// 我碰到死锁时,领域类的关键代码如下,翻开数据库day表发现自关联时生成的列为:parent_id
class Day {
String name
static belongsTo = [parent: Day]
static hasMany = [children: Day]
}
// 操作Day的服务代码简化如下
@Transactional
class DayService {
// 注意:saveDay方法会被多条线程同时调用,
// 参数day都是在各个线程中自己New出来的,
// 所以参数day是线程安全的
saveDay(def day){
// 该行代码在被多条线程同时调用时,有可能会获取到同一个dayParent
// 这里就需要注意了,有可能多条线程同时操作数据库中的同一行记录
def dayParent = getParent(day.name)
// 就是下面这行代码产生了:Deadlock found when trying to get lock; try restarting transaction
// 原因:多条线程同时操作数据库中的同一行记录,在相互等待时产生了死锁
dayParent.addToChildren(dayParent)
}
Day getParent(String name) {
def day = Day.where {
name == name
}.get()
return day
}
}
------------------------------------------------------------------
解决方法:
// 注意:saveDay方法会被多条线程同时调用,
// 参数day都是在各个线程中自己New出来的,
// 所以参数day是线程安全的
saveDay(def day){
// 该行代码在被多条线程同时调用时,有可能会获取到同一个dayParent
// 这里就需要注意了,有可能多条线程同时操作数据库中的同一行记录
def dayParent = getParent(day.name)
//dayParent.addToChildren(dayParent) // 注释掉该行代码
day.parent = dayParent // day都是线程安全的,这样写也可以达到类自相关的目的,而且还很可靠,何乐而不为呢。。。
}